This commit is contained in:
Brandon Thomas committed 2026-10-13 11:48:38 -04:00
commit 6d124d701b
3 files changed
+29 -3

No files matched your search

+21
View File
@@ -2296,4 +2296,25 @@ mod tests {
assert_eq!(s.quick_view_job(id, 1600, true).unwrap().run().quick, Some(QuickSource::Small));
let _ = std::fs::remove_dir_all(&dir);
}
/// Issue #1448: the grid renders nothing behind an unedited raw's quick thumbnail, so when the
/// embedded preview can't be read (and nothing is cached) the quick job itself must render the
/// raw, or the cell stays empty for good ("no quick preview").
#[test]
fn a_quick_thumbnail_without_an_embedded_preview_renders_the_raw() {
use crate::media::QuickSource;
let dir = std::env::temp_dir().join(format!("lc-quick-none-{}", std::process::id()));
std::fs::create_dir_all(&dir).unwrap();
let path = dir.join("a.cr3");
std::fs::write(&path, cr3_with_preview(96, 64)).unwrap();
let mut s = crate::Session::new().with_fs();
let r = s.execute("library.import", &serde_json::json!({"paths": [path.to_string_lossy()]})).unwrap();
let id = lightcraft_catalog::PhotoId(r["imported"][0].as_u64().unwrap());
s.media.preview_loader = Some(std::sync::Arc::new(|_: &str, _| None));
let job = s.thumb_job(id, 128).unwrap();
let q = s.quick_thumb_job(&job).unwrap().run();
assert_eq!((q.quick, q.key), (Some(QuickSource::Small), job.key));
assert!(q.rendered.is_ok(), "{:?}", q.rendered.err());
let _ = std::fs::remove_dir_all(&dir);
}
}
+5 -3
View File
@@ -1427,8 +1427,10 @@ impl crate::Session {
/// A first grid thumbnail for an unedited raw: the cached render for `job` (the real
/// thumbnail job, from [`Self::thumb_job`]) if there is one — then the result carries
/// [`QuickSource::Cached`] and `job.key` and is final — else its embedded preview. `None` for
/// other photos (render them directly).
/// [`QuickSource::Cached`] and `job.key` and is final — else its embedded preview, else `job`
/// itself: the grid queues no render behind an unedited raw's quick thumbnail
/// ([`Self::embedded_thumb_is_final`]), so a preview that can't be read must not leave the
/// cell empty (issue #1448). `None` for other photos (render them directly).
pub fn quick_thumb_job(&mut self, job: &RenderJob) -> Option<QuickJob> {
let p = self.catalog.photo(job.photo)?.clone();
let (path, l) = self.embedded_of(&p)?;
@@ -1439,7 +1441,7 @@ impl crate::Session {
key: job.key,
cached: job.cache.clone().into_iter().collect(),
embedded: Some((path, l, edge)),
small: None,
small: Some(Box::new(job.clone())),
})
}
+3
View File
@@ -101,6 +101,9 @@ loupe render of a cold photo finished 174 s after the click, most of it spent be
- `grid::skips_the_real_render(embedded_is_final, from_embedded)` is the decision, unit-tested:
a **cached render** as the stand-in, an **edited photo** and a **raw with no embedded JPEG** all
still render, because their thumbnail must show the pipeline's output rather than the camera's.
- Whether the embedded JPEG can actually be read is only known when the quick job runs, so
`Session::quick_thumb_job` carries the real thumbnail job as its last resort: a raw whose preview
the loader can't read renders the raw instead of leaving the cell empty (issue #1448).
- The thumbnail key still changes with the settings hash, so editing a photo re-renders its
thumbnail through the ordinary background path.