feat(label): redesign label detail view with Android-style sections
Replace the flat album grid LabelView with a rich detail page featuring: - Header with label image, name, description, and play button - Popular Tracks section (5/10/all expand, same UX as ArtistDetailView) - Releases horizontal scroll row with "See all" → LabelReleasesView - Critics' Picks section from second releases container - Playlists, Artists, and More Labels sections Backend: add /label/page and /label/explore API endpoints with V2 commands (v2_get_label_page, v2_get_label_explore). Models use serde_json::Value for flexible section parsing. Old LabelView renamed to LabelReleasesView for the "See all" flow. i18n keys added to all 4 locales (en, es, de, fr).
This commit is contained in:
1 parent
318318a3ab
commit
585053bd42
21 files changed
+2297
-461
No files matched your search
@@ -42,7 +42,8 @@ pub use playback::{PlaybackState, PlaybackStatus, QueueState, QueueTrack, Repeat
|
||||
pub use traits::{FrontendAdapter, LoggingAdapter, NoOpAdapter};
|
||||
pub use types::{
|
||||
Album, AlbumSummary, Artist, ArtistAlbums, ArtistBiography, Favorites, Genre, GenreInfo,
|
||||
GenreListContainer, GenreListResponse, ImageSet, Label, LabelDetail, Playlist,
|
||||
GenreListContainer, GenreListResponse, ImageSet, Label, LabelDetail,
|
||||
LabelExploreResponse, LabelPageContainer, LabelPageData, LabelPageGenericList, Playlist,
|
||||
PlaylistDuplicateResult, PlaylistGenre, PlaylistOwner, PlaylistWithTrackIds, Quality,
|
||||
SearchResults, SearchResultsPage, StreamRestriction, StreamUrl, Track, TracksContainer,
|
||||
UserSession,
|
||||
|
||||
@@ -353,6 +353,47 @@ pub struct LabelDetail {
|
||||
pub albums_count: Option<u32>,
|
||||
}
|
||||
|
||||
// ============ Label Page Types (/label/page) ============
|
||||
|
||||
/// Top-level response from /label/page
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct LabelPageData {
|
||||
pub id: u64,
|
||||
pub name: String,
|
||||
pub description: Option<String>,
|
||||
#[serde(default)]
|
||||
pub image: Option<serde_json::Value>,
|
||||
#[serde(default)]
|
||||
pub releases: Option<Vec<LabelPageContainer>>,
|
||||
#[serde(default)]
|
||||
pub playlists: Option<LabelPageGenericList>,
|
||||
#[serde(default)]
|
||||
pub top_tracks: Option<Vec<serde_json::Value>>,
|
||||
#[serde(default)]
|
||||
pub top_artists: Option<LabelPageGenericList>,
|
||||
}
|
||||
|
||||
/// A container within label page (e.g. releases category)
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct LabelPageContainer {
|
||||
pub id: Option<String>,
|
||||
pub data: Option<LabelPageGenericList>,
|
||||
}
|
||||
|
||||
/// Generic list with has_more and items
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct LabelPageGenericList {
|
||||
pub has_more: Option<bool>,
|
||||
pub items: Option<Vec<serde_json::Value>>,
|
||||
}
|
||||
|
||||
/// Response from /label/explore
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct LabelExploreResponse {
|
||||
pub has_more: Option<bool>,
|
||||
pub items: Option<Vec<serde_json::Value>>,
|
||||
}
|
||||
|
||||
/// Genre model
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Genre {
|
||||
|
||||
Reference in new issue
Block a user