Fix #68
This commit is contained in:
@@ -84,7 +84,9 @@ fun PlaylistScreen(
|
|||||||
|
|
||||||
val onLoad = relaunchableEffect(Unit) {
|
val onLoad = relaunchableEffect(Unit) {
|
||||||
playlist = withContext(Dispatchers.IO) {
|
playlist = withContext(Dispatchers.IO) {
|
||||||
YouTube.playlistOrAlbum(browseId)
|
YouTube.playlistOrAlbum(browseId)?.map {
|
||||||
|
it.next()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,6 +41,11 @@ object YouTube {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class EmptyBody(
|
||||||
|
val context: Context,
|
||||||
|
)
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class BrowseBody(
|
data class BrowseBody(
|
||||||
val context: Context,
|
val context: Context,
|
||||||
@@ -706,7 +711,82 @@ object YouTube {
|
|||||||
val durationText: String?,
|
val durationText: String?,
|
||||||
val album: Info<NavigationEndpoint.Endpoint.Browse>?,
|
val album: Info<NavigationEndpoint.Endpoint.Browse>?,
|
||||||
val thumbnail: ThumbnailRenderer.MusicThumbnailRenderer.Thumbnail.Thumbnail?,
|
val thumbnail: ThumbnailRenderer.MusicThumbnailRenderer.Thumbnail.Thumbnail?,
|
||||||
)
|
) {
|
||||||
|
companion object {
|
||||||
|
fun from(renderer: MusicResponsiveListItemRenderer): Item? {
|
||||||
|
return Item(
|
||||||
|
info = renderer
|
||||||
|
.flexColumns
|
||||||
|
.getOrNull(0)
|
||||||
|
?.musicResponsiveListItemFlexColumnRenderer
|
||||||
|
?.text
|
||||||
|
?.runs
|
||||||
|
?.getOrNull(0)
|
||||||
|
?.let { Info.from(it) } ?: return null,
|
||||||
|
authors = renderer
|
||||||
|
.flexColumns
|
||||||
|
.getOrNull(1)
|
||||||
|
?.musicResponsiveListItemFlexColumnRenderer
|
||||||
|
?.text
|
||||||
|
?.runs
|
||||||
|
?.map { Info.from<NavigationEndpoint.Endpoint.Browse>(it) }
|
||||||
|
?.takeIf { it.isNotEmpty() },
|
||||||
|
durationText = renderer
|
||||||
|
.fixedColumns
|
||||||
|
?.getOrNull(0)
|
||||||
|
?.musicResponsiveListItemFlexColumnRenderer
|
||||||
|
?.text
|
||||||
|
?.runs
|
||||||
|
?.getOrNull(0)
|
||||||
|
?.text,
|
||||||
|
album = renderer
|
||||||
|
.flexColumns
|
||||||
|
.getOrNull(2)
|
||||||
|
?.musicResponsiveListItemFlexColumnRenderer
|
||||||
|
?.text
|
||||||
|
?.runs
|
||||||
|
?.firstOrNull()
|
||||||
|
?.let { Info.from(it) },
|
||||||
|
thumbnail = renderer
|
||||||
|
.thumbnail
|
||||||
|
?.musicThumbnailRenderer
|
||||||
|
?.thumbnail
|
||||||
|
?.thumbnails
|
||||||
|
?.firstOrNull()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun next(): PlaylistOrAlbum {
|
||||||
|
return continuation?.let {
|
||||||
|
runCatching {
|
||||||
|
client.post("/youtubei/v1/browse") {
|
||||||
|
contentType(ContentType.Application.Json)
|
||||||
|
setBody(EmptyBody(context = Context.DefaultWeb))
|
||||||
|
parameter("key", Key)
|
||||||
|
parameter("prettyPrint", false)
|
||||||
|
parameter("continuation", continuation)
|
||||||
|
}.body<ContinuationResponse>().let { continuationResponse ->
|
||||||
|
copy(
|
||||||
|
items = items?.plus(continuationResponse
|
||||||
|
.continuationContents
|
||||||
|
.musicShelfContinuation
|
||||||
|
?.contents
|
||||||
|
?.map(MusicShelfRenderer.Content::musicResponsiveListItemRenderer)
|
||||||
|
?.mapNotNull(Item.Companion::from) ?: emptyList()),
|
||||||
|
continuation = continuationResponse
|
||||||
|
.continuationContents
|
||||||
|
.musicShelfContinuation
|
||||||
|
?.continuations
|
||||||
|
?.firstOrNull()
|
||||||
|
?.nextRadioContinuationData
|
||||||
|
?.continuation
|
||||||
|
).next()
|
||||||
|
}
|
||||||
|
}?.recoverIfCancelled()?.getOrNull()
|
||||||
|
} ?: this
|
||||||
|
}
|
||||||
|
|
||||||
suspend fun withAudioSources(): PlaylistOrAlbum {
|
suspend fun withAudioSources(): PlaylistOrAlbum {
|
||||||
@Serializable
|
@Serializable
|
||||||
@@ -788,48 +868,7 @@ object YouTube {
|
|||||||
?.musicShelfRenderer
|
?.musicShelfRenderer
|
||||||
?.contents
|
?.contents
|
||||||
?.map(MusicShelfRenderer.Content::musicResponsiveListItemRenderer)
|
?.map(MusicShelfRenderer.Content::musicResponsiveListItemRenderer)
|
||||||
?.mapNotNull { renderer ->
|
?.mapNotNull(PlaylistOrAlbum.Item.Companion::from)
|
||||||
PlaylistOrAlbum.Item(
|
|
||||||
info = renderer
|
|
||||||
.flexColumns
|
|
||||||
.getOrNull(0)
|
|
||||||
?.musicResponsiveListItemFlexColumnRenderer
|
|
||||||
?.text
|
|
||||||
?.runs
|
|
||||||
?.getOrNull(0)
|
|
||||||
?.let { Info.from(it) } ?: return@mapNotNull null,
|
|
||||||
authors = renderer
|
|
||||||
.flexColumns
|
|
||||||
.getOrNull(1)
|
|
||||||
?.musicResponsiveListItemFlexColumnRenderer
|
|
||||||
?.text
|
|
||||||
?.runs
|
|
||||||
?.map { Info.from<NavigationEndpoint.Endpoint.Browse>(it) }
|
|
||||||
?.takeIf { it.isNotEmpty() },
|
|
||||||
durationText = renderer
|
|
||||||
.fixedColumns
|
|
||||||
?.getOrNull(0)
|
|
||||||
?.musicResponsiveListItemFlexColumnRenderer
|
|
||||||
?.text
|
|
||||||
?.runs
|
|
||||||
?.getOrNull(0)
|
|
||||||
?.text,
|
|
||||||
album = renderer
|
|
||||||
.flexColumns
|
|
||||||
.getOrNull(2)
|
|
||||||
?.musicResponsiveListItemFlexColumnRenderer
|
|
||||||
?.text
|
|
||||||
?.runs
|
|
||||||
?.firstOrNull()
|
|
||||||
?.let { Info.from(it) },
|
|
||||||
thumbnail = renderer
|
|
||||||
.thumbnail
|
|
||||||
?.musicThumbnailRenderer
|
|
||||||
?.thumbnail
|
|
||||||
?.thumbnails
|
|
||||||
?.firstOrNull()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
// ?.filter { it.info.endpoint != null }
|
// ?.filter { it.info.endpoint != null }
|
||||||
,
|
,
|
||||||
url = body
|
url = body
|
||||||
@@ -844,6 +883,9 @@ object YouTube {
|
|||||||
?.tabRenderer
|
?.tabRenderer
|
||||||
?.content
|
?.content
|
||||||
?.sectionListRenderer
|
?.sectionListRenderer
|
||||||
|
?.contents
|
||||||
|
?.firstOrNull()
|
||||||
|
?.musicShelfRenderer
|
||||||
?.continuations
|
?.continuations
|
||||||
?.firstOrNull()
|
?.firstOrNull()
|
||||||
?.nextRadioContinuationData
|
?.nextRadioContinuationData
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package it.vfsfitvnm.youtubemusic.models
|
package it.vfsfitvnm.youtubemusic.models
|
||||||
|
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
import kotlinx.serialization.json.JsonNames
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class ContinuationResponse(
|
data class ContinuationResponse(
|
||||||
@@ -8,7 +9,8 @@ data class ContinuationResponse(
|
|||||||
) {
|
) {
|
||||||
@Serializable
|
@Serializable
|
||||||
data class ContinuationContents(
|
data class ContinuationContents(
|
||||||
val musicShelfContinuation: MusicShelfRenderer
|
@JsonNames("musicPlaylistShelfContinuation")
|
||||||
|
val musicShelfContinuation: MusicShelfRenderer?
|
||||||
) {
|
) {
|
||||||
// @Serializable
|
// @Serializable
|
||||||
// data class MusicShelfContinuation(
|
// data class MusicShelfContinuation(
|
||||||
|
|||||||
Reference in New Issue
Block a user