diff --git a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/localplaylist/LocalPlaylistSongList.kt b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/localplaylist/LocalPlaylistSongList.kt index f114983..56c6343 100644 --- a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/localplaylist/LocalPlaylistSongList.kt +++ b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/localplaylist/LocalPlaylistSongList.kt @@ -47,6 +47,7 @@ import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance import it.vfsfitvnm.vimusic.ui.styling.px import it.vfsfitvnm.vimusic.ui.views.SongItem import it.vfsfitvnm.vimusic.utils.asMediaItem +import it.vfsfitvnm.vimusic.utils.completed import it.vfsfitvnm.vimusic.utils.enqueue import it.vfsfitvnm.vimusic.utils.forcePlayAtIndex import it.vfsfitvnm.vimusic.utils.forcePlayFromBeginning @@ -168,8 +169,7 @@ fun LocalPlaylistSongList( transaction { runBlocking(Dispatchers.IO) { withContext(Dispatchers.IO) { - // TODO: fetch all songs! - Innertube.playlistPage(BrowseBody(browseId = browseId)) + Innertube.playlistPage(BrowseBody(browseId = browseId))?.completed() } }?.getOrNull()?.let { remotePlaylist -> Database.clearPlaylist(playlistId) diff --git a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/playlist/PlaylistSongList.kt b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/playlist/PlaylistSongList.kt index dd71efc..5d7a5d7 100644 --- a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/playlist/PlaylistSongList.kt +++ b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/playlist/PlaylistSongList.kt @@ -55,10 +55,10 @@ import it.vfsfitvnm.vimusic.ui.styling.shimmer import it.vfsfitvnm.vimusic.ui.views.SongItem import it.vfsfitvnm.vimusic.utils.asMediaItem import it.vfsfitvnm.vimusic.utils.center +import it.vfsfitvnm.vimusic.utils.completed import it.vfsfitvnm.vimusic.utils.enqueue import it.vfsfitvnm.vimusic.utils.forcePlayAtIndex import it.vfsfitvnm.vimusic.utils.forcePlayFromBeginning -import it.vfsfitvnm.vimusic.utils.produceSaveableOneShotState import it.vfsfitvnm.vimusic.utils.produceSaveableState import it.vfsfitvnm.vimusic.utils.secondary import it.vfsfitvnm.youtubemusic.Innertube @@ -77,13 +77,14 @@ fun PlaylistSongList( val binder = LocalPlayerServiceBinder.current val context = LocalContext.current - val playlistPageResult by produceSaveableOneShotState( + val playlistPageResult by produceSaveableState( initialValue = null, stateSaver = resultSaver(InnertubePlaylistOrAlbumPageSaver), ) { + if (value != null && value?.getOrNull()?.songsPage?.continuation == null) return@produceSaveableState + value = withContext(Dispatchers.IO) { - // TODO: fetch all songs! - Innertube.playlistPage(BrowseBody(browseId = browseId)) + Innertube.playlistPage(BrowseBody(browseId = browseId))?.completed() } } @@ -201,7 +202,7 @@ fun PlaylistSongList( itemsIndexed(items = playlist.songsPage?.items ?: emptyList()) { index, song -> SongItem( title = song.info?.name, - authors = (song.authors ?: playlist.authors)?.joinToString("") { it.name ?: "" }, + authors = song.authors?.joinToString("") { it.name ?: "" }, durationText = song.durationText, onClick = { playlist.songsPage?.items?.map(Innertube.SongItem::asMediaItem)?.let { mediaItems -> diff --git a/app/src/main/kotlin/it/vfsfitvnm/vimusic/utils/Utils.kt b/app/src/main/kotlin/it/vfsfitvnm/vimusic/utils/Utils.kt index d925205..a6c1e64 100644 --- a/app/src/main/kotlin/it/vfsfitvnm/vimusic/utils/Utils.kt +++ b/app/src/main/kotlin/it/vfsfitvnm/vimusic/utils/Utils.kt @@ -7,6 +7,9 @@ import androidx.media3.common.MediaItem import androidx.media3.common.MediaMetadata import it.vfsfitvnm.vimusic.models.DetailedSong 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 get() = MediaItem.Builder() @@ -88,3 +91,20 @@ fun String?.thumbnail(size: Int): String? { fun Uri?.thumbnail(size: Int): Uri? { return toString().thumbnail(size)?.toUri() } + +suspend fun Result.completed(): Result? { + 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) +}