Fix #423
This commit is contained in:
parent
7ed138ea51
commit
92141f4f49
4 changed files with 99 additions and 88 deletions
|
@ -16,7 +16,7 @@ object ArtistSaver : Saver<Artist, List<Any?>> {
|
|||
|
||||
override fun restore(value: List<Any?>): Artist = Artist(
|
||||
id = value[0] as String,
|
||||
name = value[1] as String,
|
||||
name = value[1] as String?,
|
||||
thumbnailUrl = value[2] as String?,
|
||||
info = value[3] as String?,
|
||||
timestamp = value[4] as Long?,
|
||||
|
|
|
@ -83,7 +83,7 @@ val DetailedSong.asMediaItem: MediaItem
|
|||
fun String?.thumbnail(size: Int): String? {
|
||||
return when {
|
||||
this?.startsWith("https://lh3.googleusercontent.com") == true -> "$this-w$size-h$size"
|
||||
this?.startsWith("https://yt3.ggpht.com") == true -> "$this-s$size"
|
||||
this?.startsWith("https://yt3.ggpht.com") == true -> "$this-w$size-h$size-s$size"
|
||||
else -> this
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package it.vfsfitvnm.youtubemusic.models
|
||||
|
||||
import kotlinx.serialization.ExperimentalSerializationApi
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.json.JsonNames
|
||||
|
||||
@Serializable
|
||||
data class BrowseResponse(
|
||||
|
@ -15,7 +17,8 @@ data class BrowseResponse(
|
|||
)
|
||||
|
||||
@Serializable
|
||||
data class Header(
|
||||
data class Header @OptIn(ExperimentalSerializationApi::class) constructor(
|
||||
@JsonNames("musicVisualHeaderRenderer")
|
||||
val musicImmersiveHeaderRenderer: MusicImmersiveHeaderRenderer?,
|
||||
val musicDetailHeaderRenderer: MusicDetailHeaderRenderer?,
|
||||
) {
|
||||
|
@ -33,6 +36,7 @@ data class BrowseResponse(
|
|||
val playButton: PlayButton?,
|
||||
val startRadioButton: StartRadioButton?,
|
||||
val thumbnail: ThumbnailRenderer?,
|
||||
val foregroundThumbnail: ThumbnailRenderer?,
|
||||
val title: Runs?
|
||||
) {
|
||||
@Serializable
|
||||
|
|
|
@ -13,90 +13,97 @@ import it.vfsfitvnm.youtubemusic.utils.findSectionByTitle
|
|||
import it.vfsfitvnm.youtubemusic.utils.from
|
||||
import it.vfsfitvnm.youtubemusic.utils.runCatchingNonCancellable
|
||||
|
||||
suspend fun Innertube.artistPage(body: BrowseBody): Result<Innertube.ArtistPage>? = runCatchingNonCancellable {
|
||||
val response = client.post(browse) {
|
||||
setBody(body)
|
||||
mask("contents,header")
|
||||
}.body<BrowseResponse>()
|
||||
suspend fun Innertube.artistPage(body: BrowseBody): Result<Innertube.ArtistPage>? =
|
||||
runCatchingNonCancellable {
|
||||
val response = client.post(browse) {
|
||||
setBody(body)
|
||||
mask("contents,header")
|
||||
}.body<BrowseResponse>()
|
||||
|
||||
fun findSectionByTitle(text: String): SectionListRenderer.Content? {
|
||||
return response
|
||||
.contents
|
||||
?.singleColumnBrowseResultsRenderer
|
||||
?.tabs
|
||||
?.get(0)
|
||||
?.tabRenderer
|
||||
?.content
|
||||
?.sectionListRenderer
|
||||
?.findSectionByTitle(text)
|
||||
println(response)
|
||||
|
||||
fun findSectionByTitle(text: String): SectionListRenderer.Content? {
|
||||
return response
|
||||
.contents
|
||||
?.singleColumnBrowseResultsRenderer
|
||||
?.tabs
|
||||
?.get(0)
|
||||
?.tabRenderer
|
||||
?.content
|
||||
?.sectionListRenderer
|
||||
?.findSectionByTitle(text)
|
||||
}
|
||||
|
||||
val songsSection = findSectionByTitle("Songs")?.musicShelfRenderer
|
||||
val albumsSection = findSectionByTitle("Albums")?.musicCarouselShelfRenderer
|
||||
val singlesSection = findSectionByTitle("Singles")?.musicCarouselShelfRenderer
|
||||
|
||||
Innertube.ArtistPage(
|
||||
name = response
|
||||
.header
|
||||
?.musicImmersiveHeaderRenderer
|
||||
?.title
|
||||
?.text,
|
||||
description = response
|
||||
.header
|
||||
?.musicImmersiveHeaderRenderer
|
||||
?.description
|
||||
?.text
|
||||
?.substringBeforeLast("\n\nFrom Wikipedia"),
|
||||
thumbnail = (response
|
||||
.header
|
||||
?.musicImmersiveHeaderRenderer
|
||||
?.foregroundThumbnail
|
||||
?: response
|
||||
.header
|
||||
?.musicImmersiveHeaderRenderer
|
||||
?.thumbnail)
|
||||
?.musicThumbnailRenderer
|
||||
?.thumbnail
|
||||
?.thumbnails
|
||||
?.getOrNull(0),
|
||||
shuffleEndpoint = response
|
||||
.header
|
||||
?.musicImmersiveHeaderRenderer
|
||||
?.playButton
|
||||
?.buttonRenderer
|
||||
?.navigationEndpoint
|
||||
?.watchEndpoint,
|
||||
radioEndpoint = response
|
||||
.header
|
||||
?.musicImmersiveHeaderRenderer
|
||||
?.startRadioButton
|
||||
?.buttonRenderer
|
||||
?.navigationEndpoint
|
||||
?.watchEndpoint,
|
||||
songs = songsSection
|
||||
?.contents
|
||||
?.mapNotNull(MusicShelfRenderer.Content::musicResponsiveListItemRenderer)
|
||||
?.mapNotNull(Innertube.SongItem::from),
|
||||
songsEndpoint = songsSection
|
||||
?.bottomEndpoint
|
||||
?.browseEndpoint,
|
||||
albums = albumsSection
|
||||
?.contents
|
||||
?.mapNotNull(MusicCarouselShelfRenderer.Content::musicTwoRowItemRenderer)
|
||||
?.mapNotNull(Innertube.AlbumItem::from),
|
||||
albumsEndpoint = albumsSection
|
||||
?.header
|
||||
?.musicCarouselShelfBasicHeaderRenderer
|
||||
?.moreContentButton
|
||||
?.buttonRenderer
|
||||
?.navigationEndpoint
|
||||
?.browseEndpoint,
|
||||
singles = singlesSection
|
||||
?.contents
|
||||
?.mapNotNull(MusicCarouselShelfRenderer.Content::musicTwoRowItemRenderer)
|
||||
?.mapNotNull(Innertube.AlbumItem::from),
|
||||
singlesEndpoint = singlesSection
|
||||
?.header
|
||||
?.musicCarouselShelfBasicHeaderRenderer
|
||||
?.moreContentButton
|
||||
?.buttonRenderer
|
||||
?.navigationEndpoint
|
||||
?.browseEndpoint,
|
||||
)
|
||||
}
|
||||
|
||||
val songsSection = findSectionByTitle("Songs")?.musicShelfRenderer
|
||||
val albumsSection = findSectionByTitle("Albums")?.musicCarouselShelfRenderer
|
||||
val singlesSection = findSectionByTitle("Singles")?.musicCarouselShelfRenderer
|
||||
|
||||
Innertube.ArtistPage(
|
||||
name = response
|
||||
.header
|
||||
?.musicImmersiveHeaderRenderer
|
||||
?.title
|
||||
?.text,
|
||||
description = response
|
||||
.header
|
||||
?.musicImmersiveHeaderRenderer
|
||||
?.description
|
||||
?.text
|
||||
?.substringBeforeLast("\n\nFrom Wikipedia"),
|
||||
thumbnail = response
|
||||
.header
|
||||
?.musicImmersiveHeaderRenderer
|
||||
?.thumbnail
|
||||
?.musicThumbnailRenderer
|
||||
?.thumbnail
|
||||
?.thumbnails
|
||||
?.getOrNull(0),
|
||||
shuffleEndpoint = response
|
||||
.header
|
||||
?.musicImmersiveHeaderRenderer
|
||||
?.playButton
|
||||
?.buttonRenderer
|
||||
?.navigationEndpoint
|
||||
?.watchEndpoint,
|
||||
radioEndpoint = response
|
||||
.header
|
||||
?.musicImmersiveHeaderRenderer
|
||||
?.startRadioButton
|
||||
?.buttonRenderer
|
||||
?.navigationEndpoint
|
||||
?.watchEndpoint,
|
||||
songs = songsSection
|
||||
?.contents
|
||||
?.mapNotNull(MusicShelfRenderer.Content::musicResponsiveListItemRenderer)
|
||||
?.mapNotNull(Innertube.SongItem::from),
|
||||
songsEndpoint = songsSection
|
||||
?.bottomEndpoint
|
||||
?.browseEndpoint,
|
||||
albums = albumsSection
|
||||
?.contents
|
||||
?.mapNotNull(MusicCarouselShelfRenderer.Content::musicTwoRowItemRenderer)
|
||||
?.mapNotNull(Innertube.AlbumItem::from),
|
||||
albumsEndpoint = albumsSection
|
||||
?.header
|
||||
?.musicCarouselShelfBasicHeaderRenderer
|
||||
?.moreContentButton
|
||||
?.buttonRenderer
|
||||
?.navigationEndpoint
|
||||
?.browseEndpoint,
|
||||
singles = singlesSection
|
||||
?.contents
|
||||
?.mapNotNull(MusicCarouselShelfRenderer.Content::musicTwoRowItemRenderer)
|
||||
?.mapNotNull(Innertube.AlbumItem::from),
|
||||
singlesEndpoint = singlesSection
|
||||
?.header
|
||||
?.musicCarouselShelfBasicHeaderRenderer
|
||||
?.moreContentButton
|
||||
?.buttonRenderer
|
||||
?.navigationEndpoint
|
||||
?.browseEndpoint,
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue