Say a photograph is downloading, and how far, instead of failing

The develop view reported a remote original on its way through the
error message, so it read "Could not load image" over "Downloading…".
It did so on every step along the roll, including a cached frame that
was ready within a tick, so each step flashed the error.

Waiting is now its own state. On the step, the grid's thumbnail of the
photograph stands in at once. Only when a transfer is really on the
wire does it dim under "Not on this device yet", with a line like
"Downloading — 12.4 of 38.0 MB" and a progress bar.

The bytes come from a new RemoteBackend::get_reporting. The Nextcloud
backend overrides it to read the body chunk by chunk; the default
reports once at the end. Progress is kept in the in-flight registry by
path, because a step usually lands on a frame the prefetcher is already
fetching. The catalog's file length stands in when the server sends no
Content-Length.
This commit is contained in:
2026-09-26 11:02:11 -04:00
parent 3b97195b37
commit 4bec01eaf1
9 changed files with 380 additions and 63 deletions
+28
View File
@@ -614,6 +614,34 @@ impl LibraryController {
.map(|id| dr_types::ImageId(*id as u64))
}
/// TRACES: FR-NC-6a
/// What the grid already holds for `path`: the thumbnail its cell is
/// drawing, if it has one yet, and the file's length as the scan recorded
/// it.
///
/// For the develop view while the original comes down. The thumbnail is
/// the one already decoded for the grid — no store read, no decode — and
/// the length gives the progress bar a denominator when the server sends
/// none of its own.
pub fn preview_for_path(
&self,
window: &crate::AppWindow,
path: &str,
) -> (Option<slint::Image>, Option<u64>) {
use slint::{ComponentHandle as _, Model as _};
let Some(row) = self.paths.borrow().iter().position(|p| p == path) else {
return (None, None);
};
let size = self.sizes.borrow().get(row).copied().filter(|&s| s > 0);
let thumbnail = window
.global::<crate::Library>()
.get_library_cells()
.row_data(row)
.filter(|c| c.has_thumb)
.map(|c| c.thumbnail);
(thumbnail, size)
}
/// TRACES: FR-NC-6a | FR-UI-4
/// The photographs within `depth` of `path` on the roll, closest first
/// and working outwards: next, previous, next-but-one, previous-but-one…