feat: add music_related

This commit is contained in:
ThetaDev 2022-11-11 23:41:11 +01:00
parent c80e302d72
commit cb38d5a248
11 changed files with 23236 additions and 42 deletions

View file

@ -17,6 +17,7 @@ pub(crate) use music_artist::MusicArtist;
pub(crate) use music_artist::MusicArtistAlbums;
pub(crate) use music_details::MusicDetails;
pub(crate) use music_details::MusicLyrics;
pub(crate) use music_details::MusicRelated;
pub(crate) use music_item::MusicContinuation;
pub(crate) use music_playlist::MusicPlaylist;
pub(crate) use music_search::MusicSearch;

View file

@ -3,7 +3,10 @@ use serde_with::serde_as;
use crate::serializer::text::Text;
use super::{music_item::PlaylistPanelRenderer, ContentRenderer, SectionList};
use super::{
music_item::{ItemSection, PlaylistPanelRenderer},
ContentRenderer, SectionList,
};
/// Response model for YouTube Music track details
#[derive(Debug, Deserialize)]
@ -116,3 +119,9 @@ pub(crate) struct LyricsRenderer {
#[serde_as(as = "Text")]
pub footer: String,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub(crate) struct MusicRelated {
pub contents: SectionList<ItemSection>,
}

View file

@ -27,8 +27,6 @@ pub(crate) enum ItemSection {
#[serde(alias = "musicPlaylistShelfRenderer")]
MusicShelfRenderer(MusicShelf),
MusicCarouselShelfRenderer {
#[serde(default)]
#[serde_as(as = "DefaultOnError")]
header: Option<MusicCarouselShelfHeader>,
#[serde_as(as = "VecLogError<_>")]
contents: MapResult<Vec<MusicResponseItem>>,
@ -136,13 +134,15 @@ pub(crate) struct ListMusicItem {
pub navigation_endpoint: Option<NavigationEndpoint>,
#[serde(default)]
pub flex_column_display_style: FlexColumnDisplayStyle,
#[serde(default)]
pub item_height: ItemHeight,
/// Album track number
#[serde_as(as = "Option<Text>")]
pub index: Option<String>,
pub menu: Option<MusicItemMenu>,
}
#[derive(Default, Debug, Deserialize)]
#[derive(Default, Debug, Copy, Clone, Deserialize)]
pub(crate) enum FlexColumnDisplayStyle {
#[serde(rename = "MUSIC_RESPONSIVE_LIST_ITEM_FLEX_COLUMN_DISPLAY_STYLE_TWO_LINE_STACK")]
TwoLines,
@ -151,6 +151,15 @@ pub(crate) enum FlexColumnDisplayStyle {
Default,
}
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, Deserialize)]
pub(crate) enum ItemHeight {
#[serde(rename = "MUSIC_RESPONSIVE_LIST_ITEM_HEIGHT_MEDIUM_COMPACT")]
Compact,
#[default]
#[serde(other)]
Default,
}
#[serde_as]
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
@ -295,7 +304,9 @@ pub(crate) struct MusicCarouselShelfHeader {
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub(crate) struct MusicCarouselShelfHeaderRenderer {
pub more_content_button: MoreContentButton,
pub more_content_button: Option<MoreContentButton>,
#[serde(default)]
pub title: TextComponents,
}
#[derive(Debug, Deserialize)]
@ -523,27 +534,42 @@ impl MusicListMapper {
{
// Search result
FlexColumnDisplayStyle::TwoLines => {
let mut subtitle_parts = c2
.ok_or_else(|| format!("track {}: could not get subtitle", id))?
.renderer
.text
.split(util::DOT_SEPARATOR)
.into_iter();
// Is it a podcast episode?
if subtitle_parts.len() <= 3 && c3.is_some() {
(subtitle_parts.rev().next(), None, None)
} else {
// Skip first part (track type)
if subtitle_parts.len() > 3 {
subtitle_parts.next();
}
// Is this a related track?
if !is_video && item.item_height == ItemHeight::Compact {
(
subtitle_parts.next(),
subtitle_parts.next(),
subtitle_parts.next(),
c2.map(TextComponents::from),
c3.map(TextComponents::from),
None,
)
} else {
let mut subtitle_parts = c2
.ok_or_else(|| {
format!("track {}: could not get subtitle", id)
})?
.renderer
.text
.split(util::DOT_SEPARATOR)
.into_iter();
// Is this a related video?
if item.item_height == ItemHeight::Compact {
(subtitle_parts.next(), subtitle_parts.next(), None)
}
// Is it a podcast episode?
else if subtitle_parts.len() <= 3 && c3.is_some() {
(subtitle_parts.rev().next(), None, None)
} else {
// Skip first part (track type)
if subtitle_parts.len() > 3 {
subtitle_parts.next();
}
(
subtitle_parts.next(),
subtitle_parts.next(),
subtitle_parts.next(),
)
}
}
}
// Playlist item