mirror of
https://github.com/storytold/lightcraft.git
synced 2026-11-01 05:57:09 -06:00
LRC-LIB-CATALOG-SWITCH: Try Again on a missing remembered library makes none in an empty folder (#3239)
This commit is contained in:
@@ -280,12 +280,9 @@ fn open_library_session(in_memory: bool, dir: Option<std::path::PathBuf>, rememb
|
||||
};
|
||||
if remembered && !lightcraft_engine::library::is_library(&dir) {
|
||||
log::error!("library {} is missing", dir.display());
|
||||
let why = if dir.exists() {
|
||||
"There is no LightCraft library in this folder any more."
|
||||
} else {
|
||||
"The library isn't there: it was moved or renamed, or its drive or network share isn't connected."
|
||||
};
|
||||
return (unopened(), Some(LibraryProblem::new(dir.to_string_lossy(), why)));
|
||||
let why = lightcraft_ui_egui::panels::library_problem::missing_library_reason(&dir);
|
||||
// Try Again must not make one there either (an empty mount point, issue #3239)
|
||||
return (unopened(), Some(LibraryProblem { existing_only: true, ..LibraryProblem::new(dir.to_string_lossy(), why) }));
|
||||
}
|
||||
let t0 = std::time::Instant::now();
|
||||
let mut s = Session::new().with_fs().with_default_denoise_models().with_system_clock();
|
||||
|
||||
@@ -76,12 +76,13 @@ fn a_remembered_library_missing_at_launch_is_reported_not_made_anew() {
|
||||
let problem = problem.expect("the missing library is reported");
|
||||
assert_eq!(problem.path, lib.to_string_lossy());
|
||||
assert!(problem.can_retry, "Try Again once the drive is back");
|
||||
assert!(problem.existing_only, "Try Again makes no library there either");
|
||||
assert!(!gone.exists(), "nothing is created where the library was");
|
||||
assert!(s.library.is_none() && s.catalog.is_empty(), "no library, no demo photos");
|
||||
// a remembered folder that is there but holds no library is reported too
|
||||
std::fs::create_dir_all(&lib).unwrap();
|
||||
let (s, problem) = open_session(false, &launch, true);
|
||||
assert!(problem.is_some() && s.library.is_none() && s.catalog.is_empty());
|
||||
assert!(problem.as_ref().is_some_and(|p| p.existing_only) && s.library.is_none() && s.catalog.is_empty(), "{problem:?}");
|
||||
assert!(!lightcraft_engine::library::is_library(&lib), "nothing written in it");
|
||||
// the default location (or --library) is still made when it's missing, with the demo photos
|
||||
let fresh = d.join("fresh").join("Lib");
|
||||
|
||||
@@ -345,6 +345,11 @@ pub struct LibraryProblem {
|
||||
/// Try Again reopens `path` as a library folder (`false` in the browser, whose storage isn't
|
||||
/// a folder: reloading the page tries again).
|
||||
pub can_retry: bool,
|
||||
/// Try Again opens `path` only once it holds a library again, and never makes one there: set
|
||||
/// for the library remembered in Settings that was missing at launch, whose folder can be
|
||||
/// the empty mount point of a share that isn't connected yet (issue #3239). Choose Another
|
||||
/// Library… still creates one where asked.
|
||||
pub existing_only: bool,
|
||||
/// The window lists the recent libraries to choose from instead (issue #1290); `error` then
|
||||
/// says why the last one tried didn't open.
|
||||
pub chooser: Option<Chooser>,
|
||||
@@ -714,6 +719,31 @@ fn unavailable(path: &str) -> Option<Unavailable> {
|
||||
None
|
||||
}
|
||||
|
||||
/// Why the library at `dir` that has to exist already (a remembered one, issue #3239) can't be
|
||||
/// opened: the folder is there without a catalog, or the folder itself is missing.
|
||||
pub fn missing_library_reason(dir: &Path) -> &'static str {
|
||||
if dir.exists() {
|
||||
"There is no LightCraft library in this folder any more."
|
||||
} else {
|
||||
"The library isn't there: it was moved or renamed, or its drive or network share isn't connected."
|
||||
}
|
||||
}
|
||||
|
||||
/// Try Again: reopen the problem's library. One that must exist already (`existing_only`) is
|
||||
/// opened only once its folder holds a library again (a share remounted): until then the window
|
||||
/// stays with the reason, and nothing is created there (issue #3239).
|
||||
fn retry(app: &mut LightcraftApp, problem: LibraryProblem) {
|
||||
let dir = Path::new(&problem.path);
|
||||
if problem.existing_only && !lightcraft_engine::library::is_library(dir) {
|
||||
if let Some(p) = app.library_problem.as_mut() {
|
||||
p.error = missing_library_reason(dir).to_string();
|
||||
p.dismissed = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
open(app, Some(problem.path));
|
||||
}
|
||||
|
||||
/// What the user chose.
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
enum Choice {
|
||||
@@ -811,6 +841,10 @@ fn open(app: &mut LightcraftApp, path: Option<String>) {
|
||||
}
|
||||
}
|
||||
if let Some(path) = path {
|
||||
// another library failed: Try Again may make that one, as it always could
|
||||
if p.path != path {
|
||||
p.existing_only = false;
|
||||
}
|
||||
p.path = path;
|
||||
}
|
||||
p.error = e;
|
||||
@@ -1077,7 +1111,7 @@ fn act(app: &mut LightcraftApp, choice: Choice) {
|
||||
let Some(problem) = app.library_problem.clone() else { return };
|
||||
let chosen = problem.chooser.as_ref().and_then(|c| c.selected.and_then(|i| c.libraries.get(i)).map(|l| (l.clone(), c.over)));
|
||||
match choice {
|
||||
Choice::Retry => open(app, Some(problem.path)),
|
||||
Choice::Retry => retry(app, problem),
|
||||
Choice::Choose => open(app, None),
|
||||
Choice::Open => {
|
||||
let Some((library, over)) = chosen.filter(|(l, _)| l.unavailable.is_none()) else { return };
|
||||
|
||||
@@ -1032,3 +1032,34 @@ fn found_again(multipass: bool) {
|
||||
drop(h);
|
||||
let _ = std::fs::remove_dir_all(&dir);
|
||||
}
|
||||
|
||||
/// Issue #3239: Try Again on a remembered library that was missing at launch makes no library in
|
||||
/// its folder when the folder is there but empty (a share's mount point before the share is
|
||||
/// connected): the window stays and says so. Once the folder holds the library again, it opens.
|
||||
#[test]
|
||||
fn try_again_on_a_missing_remembered_library_makes_nothing_in_an_empty_folder() {
|
||||
let dir = temp("retry-existing");
|
||||
let mount = dir.join("Share");
|
||||
std::fs::create_dir_all(&mount).unwrap();
|
||||
let path = mount.to_string_lossy().into_owned();
|
||||
let mut app = LightcraftApp::new(lightcraft_engine::Session::new().with_fs(), Services::default());
|
||||
app.library_problem = Some(LibraryProblem { existing_only: true, ..LibraryProblem::new(path.clone(), "missing") });
|
||||
let mut h = Headless::new(app, [1300.0, 900.0], 1.0);
|
||||
settle(&mut h);
|
||||
assert_eq!(h.request("ui.clickWidget", json!({"id": "button:libraryRetry"}), T)["ok"], true);
|
||||
settle(&mut h);
|
||||
assert!(!lightcraft_engine::library::is_library(&mount), "no catalog is made in the empty folder");
|
||||
assert_eq!(std::fs::read_dir(&mount).unwrap().count(), 0, "nothing is written there");
|
||||
assert!(h.app.session.library.is_none());
|
||||
let p = h.app.library_problem.as_ref().expect("the window stays");
|
||||
assert_eq!(p.error, "There is no LightCraft library in this folder any more.");
|
||||
assert!(has(&h, "button:libraryRetry"));
|
||||
// the share is connected again: Try Again opens the library in it
|
||||
make_library(&mount);
|
||||
assert_eq!(h.request("ui.clickWidget", json!({"id": "button:libraryRetry"}), T)["ok"], true);
|
||||
settle(&mut h);
|
||||
assert_eq!(h.app.session.library.as_ref().map(|l| l.dir.to_string_lossy().into_owned()), Some(path));
|
||||
assert!(h.app.library_problem.is_none());
|
||||
drop(h);
|
||||
let _ = std::fs::remove_dir_all(&dir);
|
||||
}
|
||||
|
||||
+4
-2
@@ -7,8 +7,10 @@
|
||||
yet or it was moved, the window now says it couldn't open the library and offers Try Again, Choose Another
|
||||
Library…, Continue Without Saving and Quit. Before, LightCraft quietly made a new, empty library at that path,
|
||||
filled it with the demo photos and opened it, so it looked as if the photos and edits were gone. Nothing is
|
||||
written there now. A library given with `--library` or `LIGHTCRAFT_LIBRARY`, and the default location on first
|
||||
launch, are still created as before.
|
||||
written there now, and Try Again opens the library once its drive or share is back: on an empty folder left in
|
||||
its place, such as a share's mount point, it says so again instead of making a new library there. A library
|
||||
given with `--library` or `LIGHTCRAFT_LIBRARY`, and the default location on first launch, are still created as
|
||||
before.
|
||||
|
||||
## 2026-10-24
|
||||
|
||||
|
||||
Reference in New Issue
Block a user