mirror of
https://github.com/storytold/lightcraft.git
synced 2026-10-25 18:47:42 -06:00
LR-IMP-LOCAL: Opening on Missing Photos no longer checks every original
Forgetting untouched Local records on open kept the visible photos, and on Missing Photos working them out stats every original on the UI thread before the availability worker runs. A 37k-photo library on a sleeping SMB share froze the window for minutes. Missing Photos lists library photos only, never Local records, so it can keep nothing: skip it.
This commit is contained in:
@@ -148,7 +148,11 @@ fn stamp_browsed(s: &mut Session, root: &str, files: &[String]) {
|
||||
/// referred to by an undo / redo step.
|
||||
fn in_use(s: &mut Session) -> std::collections::HashSet<PhotoId> {
|
||||
let mut keep = held(s);
|
||||
keep.extend(s.visible().iter().copied());
|
||||
// Missing Photos lists library photos only, never Local records, so it keeps nothing here; and
|
||||
// working it out checks every original (minutes on a sleeping NAS when the library opens on it)
|
||||
if s.source != crate::LibrarySource::Missing {
|
||||
keep.extend(s.visible().iter().copied());
|
||||
}
|
||||
keep
|
||||
}
|
||||
|
||||
|
||||
@@ -259,3 +259,38 @@ fn browsing_again_forgets_untouched_records_of_deleted_files() {
|
||||
assert_eq!(s.catalog.to_snapshot(), expect);
|
||||
let _ = std::fs::remove_dir_all(&root);
|
||||
}
|
||||
|
||||
/// A library last shown on Missing Photos opens without checking its originals: that view holds
|
||||
/// no Local records, so forgetting them needn't work it out (each check can wait for a sleeping
|
||||
/// NAS; a big library on one froze the window for minutes on start-up).
|
||||
#[test]
|
||||
fn opening_on_missing_photos_checks_no_originals() {
|
||||
let root = temp_dir("missing");
|
||||
let (a, lib) = (root.join("a"), root.join("lib"));
|
||||
for i in 0..5 {
|
||||
png(&a.join(format!("m{i}.png")), i);
|
||||
}
|
||||
let clock = Arc::new(Mutex::new("2026-08-01T10:00:00".to_string()));
|
||||
let mut s = open(&lib, &clock);
|
||||
s.execute("library.import", &json!({"paths": [a.to_string_lossy()], "mode": "add"})).unwrap();
|
||||
std::fs::remove_dir_all(&a).unwrap();
|
||||
s.execute("library.source", &json!({"kind": "missing"})).unwrap();
|
||||
assert_eq!(s.visible().len(), 5, "all five are missing");
|
||||
s.close_library().unwrap();
|
||||
drop(s);
|
||||
|
||||
let checks = Arc::new(std::sync::atomic::AtomicUsize::new(0));
|
||||
let mut s = Session::new().with_fs();
|
||||
let c = clock.clone();
|
||||
s.clock = Box::new(move || c.lock().unwrap().clone());
|
||||
let n = checks.clone();
|
||||
s.media.availability.set_probe(Arc::new(move |p| {
|
||||
n.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
|
||||
Path::new(p).exists()
|
||||
}));
|
||||
s.open_library(&lib, false).unwrap();
|
||||
assert_eq!(s.source, LibrarySource::Missing, "the view is restored");
|
||||
assert_eq!(checks.load(std::sync::atomic::Ordering::SeqCst), 0, "opening checked originals");
|
||||
assert!(s.library.as_ref().unwrap().forgot_local.is_some(), "forgetting still ran");
|
||||
let _ = std::fs::remove_dir_all(&root);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user