fix(api): project /favorite/getNewReleases envelope to SearchResultsPage

The endpoint returns V2GenericListDto<AlbumDto> which is just
{has_more: bool, items: [...]} — no total/offset/limit. Our caller
wants SearchResultsPage<Album> to stay compatible with the rest of
the album-list flow, so map items through directly and synthesise
total from has_more + items.len() + the offset we asked for.

Endpoint itself returns 200 OK with a real feed now (confirmed in
logs with Godsmack etc. on the test account).

cc
This commit is contained in:
vicrodh committed 2026-04-14 08:01:30 -06:00
1 parent ce375008ab
commit 37c64d252c
1 file changed
+33 -23
+33 -23
View File
@@ -819,31 +819,41 @@ impl QobuzClient {
let response: Value = serde_json::from_str(&body_text)?; let response: Value = serde_json::from_str(&body_text)?;
if let Some(obj) = response.as_object() { // Shape is V2GenericListDto<AlbumDto> per x20/b.java — a thin
log::info!( // pagination envelope: {has_more: bool, items: [...]}. No total/
"[API] get_release_watch response keys: {:?}", // offset/limit fields are returned. We only need items for the UI
obj.keys().collect::<Vec<_>>() // and the caller already knows the offset/limit it asked for, so
// we project onto SearchResultsPage<Album> to stay compatible with
// the rest of the album-list plumbing.
let items_value = response.get("items").cloned().unwrap_or(Value::Null);
let items: Vec<Album> = serde_json::from_value(items_value).map_err(|e| {
log::warn!(
"[API] get_release_watch items parse error: {}. Body (first 600 chars): {}",
e,
body_text.chars().take(600).collect::<String>()
); );
} ApiError::ApiResponse(format!("get_release_watch items parse: {}", e))
})?;
// Response is V2GenericListDto<AlbumDto> per x20/b.java. Qobuz let has_more = response
// wraps paginated album lists under `albums` by convention; try that .get("has_more")
// first, fall back to root. .and_then(|v| v.as_bool())
let page_value = response.get("albums").cloned().unwrap_or(response); .unwrap_or(false);
match serde_json::from_value::<SearchResultsPage<Album>>(page_value) {
Ok(page) => Ok(page), let total_hint = if has_more {
Err(e) => { // We don't know the real total; signal "at least one more page"
log::warn!( // by bumping past the items we have.
"[API] get_release_watch response did not match SearchResultsPage<Album>: {}. Body (first 600 chars): {}", offset + items.len() as u32 + 1
e, } else {
body_text.chars().take(600).collect::<String>() offset + items.len() as u32
); };
Err(ApiError::ApiResponse(format!(
"get_release_watch deserialize: {}", Ok(SearchResultsPage::<Album> {
e items,
))) total: total_hint,
} offset,
} limit,
})
} }
/// Get list of genres /// Get list of genres