From 1f1f1ae9f6820fcde046870da58a872ee4648127 Mon Sep 17 00:00:00 2001 From: Cameron Date: Sat, 18 Apr 2026 17:11:57 -0400 Subject: [PATCH] feat: include per-photo library id in /photos response Adds a parallel `photo_libraries: Vec` array alongside `photos` in `PhotosResponse` so clients can render per-thumbnail badges. Populated with the scoped library id at the two main return sites; left empty for `/favorites` since favorites are library-agnostic. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/data/mod.rs | 6 ++++++ src/files.rs | 4 ++++ src/main.rs | 3 +++ 3 files changed, 13 insertions(+) diff --git a/src/data/mod.rs b/src/data/mod.rs index e953f4d..fe5e183 100644 --- a/src/data/mod.rs +++ b/src/data/mod.rs @@ -102,6 +102,12 @@ pub struct PhotosResponse { pub photos: Vec, pub dirs: Vec, + /// Library id for each entry in `photos`, same length and ordering. + /// Parallel array rather than an object per row to keep the payload + /// small and backwards-compatible with older clients. + #[serde(default, skip_serializing_if = "Vec::is_empty")] + pub photo_libraries: Vec, + // Pagination metadata (only present when limit is set) #[serde(skip_serializing_if = "Option::is_none")] pub total_count: Option, diff --git a/src/files.rs b/src/files.rs index 20ea001..6fb22f1 100644 --- a/src/files.rs +++ b/src/files.rs @@ -493,9 +493,11 @@ pub async fn list_photos( .set_attribute(KeyValue::new("total_count", total_count.to_string())); span_context.span().set_status(Status::Ok); + let photo_libraries = vec![scoped_library.id; tagged_files.len()]; HttpResponse::Ok().json(PhotosResponse { photos: tagged_files, dirs: vec![], + photo_libraries, total_count: pagination_metadata.0, has_more: pagination_metadata.1, next_offset: pagination_metadata.2, @@ -778,9 +780,11 @@ pub async fn list_photos( .set_attribute(KeyValue::new("total_count", total_count.to_string())); span_context.span().set_status(Status::Ok); + let photo_libraries = vec![scoped_library.id; response_files.len()]; HttpResponse::Ok().json(PhotosResponse { photos: response_files, dirs, + photo_libraries, total_count: pagination_metadata.0, has_more: pagination_metadata.1, next_offset: pagination_metadata.2, diff --git a/src/main.rs b/src/main.rs index d03bf31..19edb78 100644 --- a/src/main.rs +++ b/src/main.rs @@ -970,9 +970,12 @@ async fn favorites( .collect::>(); span.set_status(Status::Ok); + // Favorites are library-agnostic (shared by rel_path), so we + // intentionally leave photo_libraries empty to signal "no badge". HttpResponse::Ok().json(PhotosResponse { photos: favorites, dirs: Vec::new(), + photo_libraries: Vec::new(), total_count: None, has_more: None, next_offset: None,