Clip counts on listings, so clients find photos with only clips
Derived clips (#208) aren't counted as versions, so a photo whose only derived file is a clip looked like a plain photo, and clients never fetched /image/versions for it. Summaries now carry clip_count: /photos adds the parallel array photo_clip_counts, records (memories, search, /photos/exif) carry clip_count. All skipped when zero, so other responses are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
19cbc9d59c
commit
3d1db90e3c
7 files changed
+84
-25
No files matched your search
@@ -798,10 +798,12 @@ async fn an_animated_clip_links_hides_and_is_listed_apart_from_versions() {
|
||||
);
|
||||
let app = photos_app!(fx);
|
||||
|
||||
// Hidden behind the photo, like a version, and not counted as one.
|
||||
// Hidden behind the photo, like a version, and counted as a clip, not a
|
||||
// version (so the viewer knows to fetch /image/versions for it).
|
||||
let (_, body) = get_json!(app, "/photos?path=&recursive=true&sort=nameasc");
|
||||
assert_eq!(body["photos"], serde_json::json!(["2014/IMG_1.JPG"]));
|
||||
assert!(body.get("photo_version_counts").is_none(), "{body}");
|
||||
assert_eq!(body["photo_clip_counts"], serde_json::json!([1]));
|
||||
|
||||
// Listed under `clips`, from the photo's path or the clip's own.
|
||||
for path in ["2014/IMG_1.JPG", rel] {
|
||||
|
||||
+29
-8
@@ -363,25 +363,34 @@ pub fn link_pending(
|
||||
/// responses stay byte-identical for libraries that have none.
|
||||
///
|
||||
/// `display_path` is `null` when the original is displayed, a rel_path when a
|
||||
/// version is. `/photos` carries the same facts as the parallel arrays
|
||||
/// `photo_display_paths` / `photo_version_counts` instead.
|
||||
/// version is. `clip_count` counts derived clips (videos made from the
|
||||
/// photo), which are not versions. `/photos` carries the same facts as the
|
||||
/// parallel arrays `photo_display_paths` / `photo_version_counts` /
|
||||
/// `photo_clip_counts` instead.
|
||||
#[derive(Debug, Clone, Default, serde::Serialize)]
|
||||
pub struct VersionFields {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub display_path: Option<Option<String>>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub version_count: Option<u32>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub clip_count: Option<u32>,
|
||||
}
|
||||
|
||||
impl VersionFields {
|
||||
pub fn from_summary(summary: Option<&version_dao::PhotoVersionSummary>) -> Self {
|
||||
match summary {
|
||||
Some(s) if s.version_count > 0 => VersionFields {
|
||||
display_path: Some(s.display.as_ref().map(|(_, p)| p.clone())),
|
||||
version_count: Some(s.version_count),
|
||||
},
|
||||
_ => VersionFields::default(),
|
||||
let Some(s) = summary else {
|
||||
return VersionFields::default();
|
||||
};
|
||||
let mut fields = VersionFields::default();
|
||||
if s.version_count > 0 {
|
||||
fields.display_path = Some(s.display.as_ref().map(|(_, p)| p.clone()));
|
||||
fields.version_count = Some(s.version_count);
|
||||
}
|
||||
if s.clip_count > 0 {
|
||||
fields.clip_count = Some(s.clip_count);
|
||||
}
|
||||
fields
|
||||
}
|
||||
}
|
||||
|
||||
@@ -451,6 +460,7 @@ mod tests {
|
||||
assert_eq!(json(None), serde_json::json!({"path": "a.jpg"}));
|
||||
let plain = version_dao::PhotoVersionSummary {
|
||||
version_count: 2,
|
||||
clip_count: 0,
|
||||
display: None,
|
||||
};
|
||||
assert_eq!(
|
||||
@@ -459,6 +469,7 @@ mod tests {
|
||||
);
|
||||
let shown = version_dao::PhotoVersionSummary {
|
||||
version_count: 1,
|
||||
clip_count: 0,
|
||||
display: Some((1, "aiedits/a.jpg.restored.png".into())),
|
||||
};
|
||||
assert_eq!(
|
||||
@@ -469,6 +480,16 @@ mod tests {
|
||||
"version_count": 1
|
||||
})
|
||||
);
|
||||
// Clips only: no display/version fields, just the clip count.
|
||||
let clips_only = version_dao::PhotoVersionSummary {
|
||||
version_count: 0,
|
||||
clip_count: 2,
|
||||
display: None,
|
||||
};
|
||||
assert_eq!(
|
||||
json(Some(&clips_only)),
|
||||
serde_json::json!({"path": "a.jpg", "clip_count": 2})
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in new issue
Block a user