Fetch all songs in playlist

This commit is contained in:
vfsfitvnm 2022-10-03 16:11:12 +02:00
parent d0e9c7e6b9
commit 8612814387
3 changed files with 28 additions and 7 deletions

View file

@ -47,6 +47,7 @@ import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
import it.vfsfitvnm.vimusic.ui.styling.px import it.vfsfitvnm.vimusic.ui.styling.px
import it.vfsfitvnm.vimusic.ui.views.SongItem import it.vfsfitvnm.vimusic.ui.views.SongItem
import it.vfsfitvnm.vimusic.utils.asMediaItem import it.vfsfitvnm.vimusic.utils.asMediaItem
import it.vfsfitvnm.vimusic.utils.completed
import it.vfsfitvnm.vimusic.utils.enqueue import it.vfsfitvnm.vimusic.utils.enqueue
import it.vfsfitvnm.vimusic.utils.forcePlayAtIndex import it.vfsfitvnm.vimusic.utils.forcePlayAtIndex
import it.vfsfitvnm.vimusic.utils.forcePlayFromBeginning import it.vfsfitvnm.vimusic.utils.forcePlayFromBeginning
@ -168,8 +169,7 @@ fun LocalPlaylistSongList(
transaction { transaction {
runBlocking(Dispatchers.IO) { runBlocking(Dispatchers.IO) {
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
// TODO: fetch all songs! Innertube.playlistPage(BrowseBody(browseId = browseId))?.completed()
Innertube.playlistPage(BrowseBody(browseId = browseId))
} }
}?.getOrNull()?.let { remotePlaylist -> }?.getOrNull()?.let { remotePlaylist ->
Database.clearPlaylist(playlistId) Database.clearPlaylist(playlistId)

View file

@ -55,10 +55,10 @@ import it.vfsfitvnm.vimusic.ui.styling.shimmer
import it.vfsfitvnm.vimusic.ui.views.SongItem import it.vfsfitvnm.vimusic.ui.views.SongItem
import it.vfsfitvnm.vimusic.utils.asMediaItem import it.vfsfitvnm.vimusic.utils.asMediaItem
import it.vfsfitvnm.vimusic.utils.center import it.vfsfitvnm.vimusic.utils.center
import it.vfsfitvnm.vimusic.utils.completed
import it.vfsfitvnm.vimusic.utils.enqueue import it.vfsfitvnm.vimusic.utils.enqueue
import it.vfsfitvnm.vimusic.utils.forcePlayAtIndex import it.vfsfitvnm.vimusic.utils.forcePlayAtIndex
import it.vfsfitvnm.vimusic.utils.forcePlayFromBeginning import it.vfsfitvnm.vimusic.utils.forcePlayFromBeginning
import it.vfsfitvnm.vimusic.utils.produceSaveableOneShotState
import it.vfsfitvnm.vimusic.utils.produceSaveableState import it.vfsfitvnm.vimusic.utils.produceSaveableState
import it.vfsfitvnm.vimusic.utils.secondary import it.vfsfitvnm.vimusic.utils.secondary
import it.vfsfitvnm.youtubemusic.Innertube import it.vfsfitvnm.youtubemusic.Innertube
@ -77,13 +77,14 @@ fun PlaylistSongList(
val binder = LocalPlayerServiceBinder.current val binder = LocalPlayerServiceBinder.current
val context = LocalContext.current val context = LocalContext.current
val playlistPageResult by produceSaveableOneShotState( val playlistPageResult by produceSaveableState(
initialValue = null, initialValue = null,
stateSaver = resultSaver(InnertubePlaylistOrAlbumPageSaver), stateSaver = resultSaver(InnertubePlaylistOrAlbumPageSaver),
) { ) {
if (value != null && value?.getOrNull()?.songsPage?.continuation == null) return@produceSaveableState
value = withContext(Dispatchers.IO) { value = withContext(Dispatchers.IO) {
// TODO: fetch all songs! Innertube.playlistPage(BrowseBody(browseId = browseId))?.completed()
Innertube.playlistPage(BrowseBody(browseId = browseId))
} }
} }
@ -201,7 +202,7 @@ fun PlaylistSongList(
itemsIndexed(items = playlist.songsPage?.items ?: emptyList()) { index, song -> itemsIndexed(items = playlist.songsPage?.items ?: emptyList()) { index, song ->
SongItem( SongItem(
title = song.info?.name, title = song.info?.name,
authors = (song.authors ?: playlist.authors)?.joinToString("") { it.name ?: "" }, authors = song.authors?.joinToString("") { it.name ?: "" },
durationText = song.durationText, durationText = song.durationText,
onClick = { onClick = {
playlist.songsPage?.items?.map(Innertube.SongItem::asMediaItem)?.let { mediaItems -> playlist.songsPage?.items?.map(Innertube.SongItem::asMediaItem)?.let { mediaItems ->

View file

@ -7,6 +7,9 @@ import androidx.media3.common.MediaItem
import androidx.media3.common.MediaMetadata import androidx.media3.common.MediaMetadata
import it.vfsfitvnm.vimusic.models.DetailedSong import it.vfsfitvnm.vimusic.models.DetailedSong
import it.vfsfitvnm.youtubemusic.Innertube import it.vfsfitvnm.youtubemusic.Innertube
import it.vfsfitvnm.youtubemusic.models.bodies.ContinuationBody
import it.vfsfitvnm.youtubemusic.requests.playlistPage
import it.vfsfitvnm.youtubemusic.utils.plus
val Innertube.SongItem.asMediaItem: MediaItem val Innertube.SongItem.asMediaItem: MediaItem
get() = MediaItem.Builder() get() = MediaItem.Builder()
@ -88,3 +91,20 @@ fun String?.thumbnail(size: Int): String? {
fun Uri?.thumbnail(size: Int): Uri? { fun Uri?.thumbnail(size: Int): Uri? {
return toString().thumbnail(size)?.toUri() return toString().thumbnail(size)?.toUri()
} }
suspend fun Result<Innertube.PlaylistOrAlbumPage>.completed(): Result<Innertube.PlaylistOrAlbumPage>? {
var playlistPage = getOrNull() ?: return null
while (playlistPage.songsPage?.continuation != null) {
val continuation = playlistPage.songsPage?.continuation!!
val otherPlaylistPageResult = Innertube.playlistPage(ContinuationBody(continuation = continuation)) ?: break
if (otherPlaylistPageResult.isFailure) break
otherPlaylistPageResult.getOrNull()?.let { otherSongsPage ->
playlistPage = playlistPage.copy(songsPage = playlistPage.songsPage + otherSongsPage)
}
}
return Result.success(playlistPage)
}