Keep a stepped-past download from replacing the open photograph
Opening a photograph from the library starts a download and a timer that polls for it. Every step along the roll started another, and each one put its result on screen when it landed, so a frame stepped past earlier could arrive last and replace the one whose name was showing. Each open now takes a generation number; a download that lands for an older generation is recorded in the activity list (its bytes are cached) and goes no further. The outgoing session also stayed live until the new download landed. Its sliders kept working, and a second step before the first landed saved that session's edit under the new photograph's identity. The session is now dropped as soon as its edit is saved.
This commit is contained in:
@@ -2670,6 +2670,14 @@ fn wire_remote_open(
|
||||
let inspection = inspection.clone();
|
||||
let prefetch = prefetch.clone();
|
||||
|
||||
// Which open is the current one. Every open starts its own download and
|
||||
// its own timer, and a walk along the roll starts one per press — so the
|
||||
// transfers land in whatever order the network finishes them, not the
|
||||
// order they were asked for. Without this the photograph stepped past
|
||||
// three presses ago could arrive last and replace the one whose name is
|
||||
// on screen, and its edit would then be saved under that name.
|
||||
let current = Rc::new(Cell::new(0u64));
|
||||
|
||||
{
|
||||
let weak = window.as_weak();
|
||||
let library = library.clone();
|
||||
@@ -2689,6 +2697,18 @@ fn wire_remote_open(
|
||||
// before the identity below is overwritten.
|
||||
presets::save_open_edit(&w, &open_image.borrow(), &session, &library);
|
||||
|
||||
// And let the outgoing session go now, not when the download
|
||||
// lands. Kept, its sliders stayed live over a photograph that was
|
||||
// no longer the open one, and a second step before the first
|
||||
// landed saved *that* session's edit under the new photograph's
|
||||
// identity, which is set a few lines below.
|
||||
*session.borrow_mut() = None;
|
||||
rows.set_vec(Vec::<ParamRow>::new());
|
||||
w.global::<Develop>().set_enabled(false);
|
||||
|
||||
current.set(current.get() + 1);
|
||||
let mine = current.get();
|
||||
|
||||
let name = path.rsplit('/').next().unwrap_or(&path).to_string();
|
||||
reset_view_state(&w);
|
||||
w.set_filename(name.clone().into());
|
||||
@@ -2748,6 +2768,7 @@ fn wire_remote_open(
|
||||
}
|
||||
|
||||
log::info!("fetching {path} for develop");
|
||||
|
||||
w.set_load_error("Downloading…".into());
|
||||
|
||||
let rx = library::spawn_full_fetch(conn, path.clone(), cache);
|
||||
@@ -2774,6 +2795,7 @@ fn wire_remote_open(
|
||||
let path = path.clone();
|
||||
let viewport = viewport.clone();
|
||||
let inspection = inspection.clone();
|
||||
let current = current.clone();
|
||||
let sidecar_rx = Rc::new(sidecar_rx);
|
||||
let timer = Rc::new(slint::Timer::default());
|
||||
let held = timer.clone();
|
||||
@@ -2786,6 +2808,18 @@ fn wire_remote_open(
|
||||
held.stop();
|
||||
let Some(w) = weak.upgrade() else { return };
|
||||
|
||||
// Stepped past while it was coming down. The transfer
|
||||
// still counts — it is in the cache, and the step back
|
||||
// will be a disk read — but it is not what is on screen.
|
||||
if current.get() != mine {
|
||||
match &got {
|
||||
Ok(b) => job.finish(activity::describe_bytes(b.len() as u64)),
|
||||
Err(e) => job.fail(e.message.clone()),
|
||||
}
|
||||
log::debug!("{name}: landed after the view moved on");
|
||||
return;
|
||||
}
|
||||
|
||||
let bytes = match got {
|
||||
Ok(b) => b,
|
||||
Err(e) => {
|
||||
|
||||
Reference in New Issue
Block a user