fix(qt): album carousel cards — artist fallback and similar-album genre
Two card-data gaps on the album page's bottom rails: - "Listening suggestions" (/album/suggest) rendered no artist line: the Qt mapping read only the flat `artist` field, while Slint's album_map::album_artist falls back to the artists[] array (main-artist role, else first entry) — the shape /album/suggest actually returns for some albums. The fallback is ported as card_artist. - "Similar albums" (Last.fm row) showed no genre in the hover overlay: AlbumReco carried no genre at all. build_album_reco has the resolving Qobuz Album in hand, so the field now exists (serde-defaulted, so cached reco JSON keeps working) and is mapped through. Slint's external_reco::album_card can map it too after the next merge — its checkout is a different branch and is untouched here. km
This commit is contained in:
3 files changed
+40
-3
No files matched your search
@@ -76,6 +76,11 @@ pub struct AlbumReco {
|
||||
pub artwork_url: String,
|
||||
#[serde(default)]
|
||||
pub subtitle: String,
|
||||
/// Genre name from the resolving Qobuz album — feeds the card hover
|
||||
/// overlay. Defaulted for backward compatibility with cached JSON
|
||||
/// written before the field existed.
|
||||
#[serde(default)]
|
||||
pub genre: String,
|
||||
#[serde(default = "default_source")]
|
||||
pub source: RecoSource,
|
||||
}
|
||||
|
||||
@@ -284,6 +284,11 @@ pub fn build_album_reco(album: &Album, subtitle: String, source: RecoSource) ->
|
||||
quality_label,
|
||||
artwork_url: album.image.best().cloned().unwrap_or_default(),
|
||||
subtitle,
|
||||
genre: album
|
||||
.genre
|
||||
.as_ref()
|
||||
.map(|g| g.name.clone())
|
||||
.unwrap_or_default(),
|
||||
source,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -635,6 +635,32 @@ pub(crate) fn format_album_title(title: &str, version: Option<&str>) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
/// album_map.rs `album_artist` (Slint `qbz/src/album_map.rs:168-187`):
|
||||
/// `artist.name` first, then the `artists[]` array (the entry with the
|
||||
/// `main-artist` role, else the first entry). `/album/suggest` returns items
|
||||
/// whose flat `artist` is empty but whose `artists[]` is populated — without
|
||||
/// the fallback the "Listening suggestions" cards render no artist line.
|
||||
fn card_artist(album: &Album) -> (String, String) {
|
||||
if !album.artist.name.is_empty() {
|
||||
return (album.artist.name.clone(), album.artist.id.to_string());
|
||||
}
|
||||
if let Some(list) = album.artists.as_ref() {
|
||||
let pick = list
|
||||
.iter()
|
||||
.find(|a| {
|
||||
a.roles
|
||||
.as_ref()
|
||||
.map(|r| r.iter().any(|role| role == "main-artist"))
|
||||
.unwrap_or(false)
|
||||
})
|
||||
.or_else(|| list.first());
|
||||
if let Some(a) = pick {
|
||||
return (a.name.clone(), a.id.to_string());
|
||||
}
|
||||
}
|
||||
(String::new(), String::new())
|
||||
}
|
||||
|
||||
/// artist.rs `map_release` for carousel cards (deduped vs the open album).
|
||||
fn map_release_card(release: &qbz_models::PageArtistRelease) -> AlbumCardData {
|
||||
let artist = release
|
||||
@@ -727,7 +753,7 @@ fn reco_to_card(r: qbz_external_reco::AlbumReco) -> AlbumCardData {
|
||||
title: r.title,
|
||||
artist: r.artist,
|
||||
artist_id: r.artist_id,
|
||||
genre: String::new(),
|
||||
genre: r.genre,
|
||||
year: r.year,
|
||||
quality_tier: r.quality_tier,
|
||||
quality_detail: r.quality_label,
|
||||
@@ -767,13 +793,14 @@ pub async fn load_suggestions(
|
||||
.as_ref()
|
||||
.and_then(|d| d.original.clone().or(d.download.clone()).or(d.stream.clone()))
|
||||
.or(a.release_date_original.clone());
|
||||
let (artist, card_artist_id) = card_artist(a);
|
||||
AlbumCardData {
|
||||
is_pinned: crate::sidebar_qt::is_pinned("album", &a.id),
|
||||
is_favorite: crate::fav_cache_qt::is_album_favorite(&a.id),
|
||||
id: a.id.clone(),
|
||||
title: a.title.clone(),
|
||||
artist: a.artist.name.clone(),
|
||||
artist_id: a.artist.id.to_string(),
|
||||
artist,
|
||||
artist_id: card_artist_id,
|
||||
genre: a.genre.as_ref().map(|g| g.name.clone()).unwrap_or_default(),
|
||||
year: qbz_text_utils::dates::release_label(date.as_deref()),
|
||||
quality_tier: home_qt::quality_tier_from_depth(bit_depth).to_string(),
|
||||
|
||||
Reference in new issue
Block a user