feat(album): plumb featured artists and parental warning
Add Album.parental_warning and Album.artists (with the new AlbumArtist struct) to qbz-models so the /album/get response surfaces both fields. Mirror them in the QobuzAlbum / AlbumDetail TypeScript types and populate featuredArtists (filtered to non-main contributors) and parentalWarning in convertQobuzAlbum. Wire onFeaturedArtistClick from the route so featured artist names route to their discography. cc
This commit is contained in:
4 files changed
+34
No files matched your search
@@ -273,6 +273,23 @@ pub struct Album {
|
||||
/// Editorial awards (Qobuzissime, Album of the Week, press accolades).
|
||||
#[serde(default)]
|
||||
pub awards: Option<Vec<AlbumAward>>,
|
||||
/// Parental advisory / explicit content marker.
|
||||
#[serde(default)]
|
||||
pub parental_warning: Option<bool>,
|
||||
/// Full artist contributor list including roles. The primary artist is
|
||||
/// duplicated here as `roles: ["main-artist"]`; non-main entries are
|
||||
/// the album's featured artists.
|
||||
#[serde(default)]
|
||||
pub artists: Option<Vec<AlbumArtist>>,
|
||||
}
|
||||
|
||||
/// Album artist contributor entry (main artist + featured artists).
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct AlbumArtist {
|
||||
pub id: u64,
|
||||
pub name: String,
|
||||
#[serde(default)]
|
||||
pub roles: Option<Vec<String>>,
|
||||
}
|
||||
|
||||
/// A downloadable extra bundled with an album (e.g. PDF booklet)
|
||||
|
||||
@@ -358,12 +358,23 @@ export function convertQobuzAlbum(album: QobuzAlbum): AlbumDetail {
|
||||
album.maximum_sampling_rate
|
||||
);
|
||||
|
||||
const mainArtistId = album.artist?.id;
|
||||
const featuredArtists = (album.artists ?? [])
|
||||
.filter((entry) => {
|
||||
const isMain = entry.roles?.some((role) => role === 'main-artist');
|
||||
const isMainById = mainArtistId !== undefined && entry.id === mainArtistId;
|
||||
return !isMain && !isMainById;
|
||||
})
|
||||
.map((entry) => ({ id: entry.id, name: entry.name }));
|
||||
|
||||
return {
|
||||
id: album.id,
|
||||
artwork,
|
||||
title: album.title,
|
||||
artist: album.artist?.name || 'Unknown Artist',
|
||||
artistId: album.artist?.id,
|
||||
featuredArtists: featuredArtists.length > 0 ? featuredArtists : undefined,
|
||||
parentalWarning: album.parental_warning ?? false,
|
||||
year: album.release_date_original?.split('-')[0] || '',
|
||||
releaseDate: album.release_date_original,
|
||||
label: album.label?.name || '',
|
||||
|
||||
@@ -96,6 +96,7 @@ export interface QobuzAlbum {
|
||||
title: string;
|
||||
description?: string;
|
||||
artist: { id?: number; name: string };
|
||||
artists?: { id: number; name: string; roles?: string[] }[];
|
||||
image: QobuzImage;
|
||||
release_date_original?: string;
|
||||
hires_streamable?: boolean;
|
||||
@@ -202,6 +203,10 @@ export interface AlbumDetail {
|
||||
title: string;
|
||||
artist: string;
|
||||
artistId?: number;
|
||||
/** Featured artists (excluding the main artist), in API order. */
|
||||
featuredArtists?: { id: number; name: string }[];
|
||||
/** Parental advisory marker — show explicit badge next to artist line. */
|
||||
parentalWarning?: boolean;
|
||||
year: string;
|
||||
releaseDate?: string; // Full date in YYYY-MM-DD format
|
||||
label: string;
|
||||
|
||||
@@ -5922,6 +5922,7 @@
|
||||
isPlaybackActive={isPlaying}
|
||||
onBack={navGoBack}
|
||||
onArtistClick={() => selectedAlbum?.artistId && handleArtistClick(selectedAlbum.artistId)}
|
||||
onFeaturedArtistClick={(artistId) => handleArtistClick(artistId)}
|
||||
onLabelClick={handleLabelClick}
|
||||
onAwardClick={handleAwardClick}
|
||||
onTrackPlay={handleAlbumTrackPlay}
|
||||
|
||||
Reference in new issue
Block a user