feat: include per-photo library id in /photos response
Adds a parallel `photo_libraries: Vec<i32>` 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) <noreply@anthropic.com>
This commit is contained in:
@@ -102,6 +102,12 @@ pub struct PhotosResponse {
|
|||||||
pub photos: Vec<String>,
|
pub photos: Vec<String>,
|
||||||
pub dirs: Vec<String>,
|
pub dirs: Vec<String>,
|
||||||
|
|
||||||
|
/// 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<i32>,
|
||||||
|
|
||||||
// Pagination metadata (only present when limit is set)
|
// Pagination metadata (only present when limit is set)
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub total_count: Option<i64>,
|
pub total_count: Option<i64>,
|
||||||
|
|||||||
@@ -493,9 +493,11 @@ pub async fn list_photos<TagD: TagDao, FS: FileSystemAccess>(
|
|||||||
.set_attribute(KeyValue::new("total_count", total_count.to_string()));
|
.set_attribute(KeyValue::new("total_count", total_count.to_string()));
|
||||||
span_context.span().set_status(Status::Ok);
|
span_context.span().set_status(Status::Ok);
|
||||||
|
|
||||||
|
let photo_libraries = vec![scoped_library.id; tagged_files.len()];
|
||||||
HttpResponse::Ok().json(PhotosResponse {
|
HttpResponse::Ok().json(PhotosResponse {
|
||||||
photos: tagged_files,
|
photos: tagged_files,
|
||||||
dirs: vec![],
|
dirs: vec![],
|
||||||
|
photo_libraries,
|
||||||
total_count: pagination_metadata.0,
|
total_count: pagination_metadata.0,
|
||||||
has_more: pagination_metadata.1,
|
has_more: pagination_metadata.1,
|
||||||
next_offset: pagination_metadata.2,
|
next_offset: pagination_metadata.2,
|
||||||
@@ -778,9 +780,11 @@ pub async fn list_photos<TagD: TagDao, FS: FileSystemAccess>(
|
|||||||
.set_attribute(KeyValue::new("total_count", total_count.to_string()));
|
.set_attribute(KeyValue::new("total_count", total_count.to_string()));
|
||||||
span_context.span().set_status(Status::Ok);
|
span_context.span().set_status(Status::Ok);
|
||||||
|
|
||||||
|
let photo_libraries = vec![scoped_library.id; response_files.len()];
|
||||||
HttpResponse::Ok().json(PhotosResponse {
|
HttpResponse::Ok().json(PhotosResponse {
|
||||||
photos: response_files,
|
photos: response_files,
|
||||||
dirs,
|
dirs,
|
||||||
|
photo_libraries,
|
||||||
total_count: pagination_metadata.0,
|
total_count: pagination_metadata.0,
|
||||||
has_more: pagination_metadata.1,
|
has_more: pagination_metadata.1,
|
||||||
next_offset: pagination_metadata.2,
|
next_offset: pagination_metadata.2,
|
||||||
|
|||||||
@@ -970,9 +970,12 @@ async fn favorites(
|
|||||||
.collect::<Vec<String>>();
|
.collect::<Vec<String>>();
|
||||||
|
|
||||||
span.set_status(Status::Ok);
|
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 {
|
HttpResponse::Ok().json(PhotosResponse {
|
||||||
photos: favorites,
|
photos: favorites,
|
||||||
dirs: Vec::new(),
|
dirs: Vec::new(),
|
||||||
|
photo_libraries: Vec::new(),
|
||||||
total_count: None,
|
total_count: None,
|
||||||
has_more: None,
|
has_more: None,
|
||||||
next_offset: None,
|
next_offset: None,
|
||||||
|
|||||||
Reference in New Issue
Block a user