From b74517debbc019f5edf15146ceb75387dd294dbc Mon Sep 17 00:00:00 2001 From: vfsfitvnm Date: Fri, 12 Aug 2022 14:25:49 +0200 Subject: [PATCH] Update album fetch logic --- .../kotlin/it/vfsfitvnm/vimusic/Database.kt | 2 +- .../vimusic/service/BitmapProvider.kt | 1 - .../vimusic/ui/screens/AlbumScreen.kt | 46 ++++++++++--------- .../vimusic/ui/screens/PlaylistScreen.kt | 2 +- .../it/vfsfitvnm/youtubemusic/YouTube.kt | 18 +++++--- 5 files changed, 39 insertions(+), 30 deletions(-) diff --git a/app/src/main/kotlin/it/vfsfitvnm/vimusic/Database.kt b/app/src/main/kotlin/it/vfsfitvnm/vimusic/Database.kt index 2def87e..586b621 100644 --- a/app/src/main/kotlin/it/vfsfitvnm/vimusic/Database.kt +++ b/app/src/main/kotlin/it/vfsfitvnm/vimusic/Database.kt @@ -138,7 +138,7 @@ interface Database { fun artist(id: String): Flow @Query("SELECT * FROM Album WHERE id = :id") - fun album(id: String): Flow + fun album(id: String): Album? @Query("UPDATE Song SET totalPlayTimeMs = totalPlayTimeMs + :addition WHERE id = :id") fun incrementTotalPlayTimeMs(id: String, addition: Long) diff --git a/app/src/main/kotlin/it/vfsfitvnm/vimusic/service/BitmapProvider.kt b/app/src/main/kotlin/it/vfsfitvnm/vimusic/service/BitmapProvider.kt index 10262a4..3f8e3e0 100644 --- a/app/src/main/kotlin/it/vfsfitvnm/vimusic/service/BitmapProvider.kt +++ b/app/src/main/kotlin/it/vfsfitvnm/vimusic/service/BitmapProvider.kt @@ -72,7 +72,6 @@ class BitmapProvider( onSuccess = { _, result -> lastBitmap = (result.drawable as BitmapDrawable).bitmap onDone(bitmap) - println("invoking listener") listener?.invoke(lastBitmap) } ) diff --git a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/AlbumScreen.kt b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/AlbumScreen.kt index 9d5dcfc..e77d690 100644 --- a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/AlbumScreen.kt +++ b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/AlbumScreen.kt @@ -27,6 +27,7 @@ import androidx.compose.foundation.text.BasicText import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue +import androidx.compose.runtime.produceState import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -78,23 +79,22 @@ import it.vfsfitvnm.youtubemusic.YouTube import java.text.DateFormat import java.util.Date import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.map import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.withContext @ExperimentalAnimationApi @Composable fun AlbumScreen(browseId: String) { val lazyListState = rememberLazyListState() - val albumResult by remember(browseId) { - Database.album(browseId).map { album -> - album - ?.takeIf { album.timestamp != null } + val albumResult by produceState?>(initialValue = null, browseId) { + value = withContext(Dispatchers.IO) { + Database.album(browseId) + ?.takeIf { it.timestamp != null } ?.let(Result.Companion::success) ?: fetchAlbum(browseId) - }.distinctUntilChanged() - }.collectAsState(initial = null, context = Dispatchers.IO) + } + } val songs by remember(browseId) { Database.albumSongs(browseId) @@ -404,9 +404,9 @@ private fun LoadingOrError( } private suspend fun fetchAlbum(browseId: String): Result? { - return YouTube.playlistOrAlbum(browseId) + return YouTube.album(browseId) ?.map { youtubeAlbum -> - Album( + val album = Album( id = browseId, title = youtubeAlbum.title, thumbnailUrl = youtubeAlbum.thumbnail?.url, @@ -414,19 +414,23 @@ private suspend fun fetchAlbum(browseId: String): Result? { authorsText = youtubeAlbum.authors?.joinToString("") { it.name }, shareUrl = youtubeAlbum.url, timestamp = System.currentTimeMillis() - ).also(Database::upsert).also { - youtubeAlbum.withAudioSources()?.getOrNull()?.items?.forEachIndexed { position, albumItem -> - albumItem.toMediaItem(browseId, youtubeAlbum)?.let { mediaItem -> - Database.insert(mediaItem) - Database.upsert( - SongAlbumMap( - songId = mediaItem.mediaId, - albumId = browseId, - position = position - ) + ) + + Database.upsert(album) + + youtubeAlbum.items?.forEachIndexed { position, albumItem -> + albumItem.toMediaItem(browseId, youtubeAlbum)?.let { mediaItem -> + Database.insert(mediaItem) + Database.upsert( + SongAlbumMap( + songId = mediaItem.mediaId, + albumId = browseId, + position = position ) - } + ) } } + + album } } diff --git a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/PlaylistScreen.kt b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/PlaylistScreen.kt index a61cd3a..bb43b88 100644 --- a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/PlaylistScreen.kt +++ b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/PlaylistScreen.kt @@ -102,7 +102,7 @@ fun PlaylistScreen(browseId: String) { val onLoad = relaunchableEffect(Unit) { playlist = withContext(Dispatchers.IO) { - YouTube.playlistOrAlbum(browseId)?.map { + YouTube.playlist(browseId)?.map { it.next() }?.map { playlist -> playlist.copy(items = playlist.items?.filter { it.info.endpoint != null }) diff --git a/youtube-music/src/main/kotlin/it/vfsfitvnm/youtubemusic/YouTube.kt b/youtube-music/src/main/kotlin/it/vfsfitvnm/youtubemusic/YouTube.kt index 2dff732..c7b8248 100644 --- a/youtube-music/src/main/kotlin/it/vfsfitvnm/youtubemusic/YouTube.kt +++ b/youtube-music/src/main/kotlin/it/vfsfitvnm/youtubemusic/YouTube.kt @@ -882,17 +882,23 @@ object YouTube { }.recoverIfCancelled()?.getOrNull() } ?: this } + } - suspend fun withAudioSources(): Result? { - return url?.let { Url(it).parameters["list"] }?.let { playlistId -> - playlistOrAlbum("VL$playlistId")?.map { playlist -> - copy(items = playlist.items) + suspend fun album(browseId: String): Result? { + return playlistOrAlbum(browseId)?.map { album -> + album.url?.let { Url(it).parameters["list"] }?.let { playlistId -> + playlistOrAlbum("VL$playlistId")?.getOrNull()?.let { playlist -> + album.copy(items = playlist.items) } - } + } ?: album } } - suspend fun playlistOrAlbum(browseId: String): Result? { + suspend fun playlist(browseId: String): Result? { + return playlistOrAlbum(browseId) + } + + private suspend fun playlistOrAlbum(browseId: String): Result? { return browse(browseId)?.map { body -> PlaylistOrAlbum( title = body