Update album fetch logic
This commit is contained in:
@@ -138,7 +138,7 @@ interface Database {
|
|||||||
fun artist(id: String): Flow<Artist?>
|
fun artist(id: String): Flow<Artist?>
|
||||||
|
|
||||||
@Query("SELECT * FROM Album WHERE id = :id")
|
@Query("SELECT * FROM Album WHERE id = :id")
|
||||||
fun album(id: String): Flow<Album?>
|
fun album(id: String): Album?
|
||||||
|
|
||||||
@Query("UPDATE Song SET totalPlayTimeMs = totalPlayTimeMs + :addition WHERE id = :id")
|
@Query("UPDATE Song SET totalPlayTimeMs = totalPlayTimeMs + :addition WHERE id = :id")
|
||||||
fun incrementTotalPlayTimeMs(id: String, addition: Long)
|
fun incrementTotalPlayTimeMs(id: String, addition: Long)
|
||||||
|
|||||||
@@ -72,7 +72,6 @@ class BitmapProvider(
|
|||||||
onSuccess = { _, result ->
|
onSuccess = { _, result ->
|
||||||
lastBitmap = (result.drawable as BitmapDrawable).bitmap
|
lastBitmap = (result.drawable as BitmapDrawable).bitmap
|
||||||
onDone(bitmap)
|
onDone(bitmap)
|
||||||
println("invoking listener")
|
|
||||||
listener?.invoke(lastBitmap)
|
listener?.invoke(lastBitmap)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import androidx.compose.foundation.text.BasicText
|
|||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.produceState
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
@@ -78,23 +79,22 @@ import it.vfsfitvnm.youtubemusic.YouTube
|
|||||||
import java.text.DateFormat
|
import java.text.DateFormat
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
|
||||||
import kotlinx.coroutines.flow.map
|
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
@ExperimentalAnimationApi
|
@ExperimentalAnimationApi
|
||||||
@Composable
|
@Composable
|
||||||
fun AlbumScreen(browseId: String) {
|
fun AlbumScreen(browseId: String) {
|
||||||
val lazyListState = rememberLazyListState()
|
val lazyListState = rememberLazyListState()
|
||||||
|
|
||||||
val albumResult by remember(browseId) {
|
val albumResult by produceState<Result<Album>?>(initialValue = null, browseId) {
|
||||||
Database.album(browseId).map { album ->
|
value = withContext(Dispatchers.IO) {
|
||||||
album
|
Database.album(browseId)
|
||||||
?.takeIf { album.timestamp != null }
|
?.takeIf { it.timestamp != null }
|
||||||
?.let(Result.Companion::success)
|
?.let(Result.Companion::success)
|
||||||
?: fetchAlbum(browseId)
|
?: fetchAlbum(browseId)
|
||||||
}.distinctUntilChanged()
|
}
|
||||||
}.collectAsState(initial = null, context = Dispatchers.IO)
|
}
|
||||||
|
|
||||||
val songs by remember(browseId) {
|
val songs by remember(browseId) {
|
||||||
Database.albumSongs(browseId)
|
Database.albumSongs(browseId)
|
||||||
@@ -404,9 +404,9 @@ private fun LoadingOrError(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun fetchAlbum(browseId: String): Result<Album>? {
|
private suspend fun fetchAlbum(browseId: String): Result<Album>? {
|
||||||
return YouTube.playlistOrAlbum(browseId)
|
return YouTube.album(browseId)
|
||||||
?.map { youtubeAlbum ->
|
?.map { youtubeAlbum ->
|
||||||
Album(
|
val album = Album(
|
||||||
id = browseId,
|
id = browseId,
|
||||||
title = youtubeAlbum.title,
|
title = youtubeAlbum.title,
|
||||||
thumbnailUrl = youtubeAlbum.thumbnail?.url,
|
thumbnailUrl = youtubeAlbum.thumbnail?.url,
|
||||||
@@ -414,19 +414,23 @@ private suspend fun fetchAlbum(browseId: String): Result<Album>? {
|
|||||||
authorsText = youtubeAlbum.authors?.joinToString("") { it.name },
|
authorsText = youtubeAlbum.authors?.joinToString("") { it.name },
|
||||||
shareUrl = youtubeAlbum.url,
|
shareUrl = youtubeAlbum.url,
|
||||||
timestamp = System.currentTimeMillis()
|
timestamp = System.currentTimeMillis()
|
||||||
).also(Database::upsert).also {
|
)
|
||||||
youtubeAlbum.withAudioSources()?.getOrNull()?.items?.forEachIndexed { position, albumItem ->
|
|
||||||
albumItem.toMediaItem(browseId, youtubeAlbum)?.let { mediaItem ->
|
Database.upsert(album)
|
||||||
Database.insert(mediaItem)
|
|
||||||
Database.upsert(
|
youtubeAlbum.items?.forEachIndexed { position, albumItem ->
|
||||||
SongAlbumMap(
|
albumItem.toMediaItem(browseId, youtubeAlbum)?.let { mediaItem ->
|
||||||
songId = mediaItem.mediaId,
|
Database.insert(mediaItem)
|
||||||
albumId = browseId,
|
Database.upsert(
|
||||||
position = position
|
SongAlbumMap(
|
||||||
)
|
songId = mediaItem.mediaId,
|
||||||
|
albumId = browseId,
|
||||||
|
position = position
|
||||||
)
|
)
|
||||||
}
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
album
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ fun PlaylistScreen(browseId: String) {
|
|||||||
|
|
||||||
val onLoad = relaunchableEffect(Unit) {
|
val onLoad = relaunchableEffect(Unit) {
|
||||||
playlist = withContext(Dispatchers.IO) {
|
playlist = withContext(Dispatchers.IO) {
|
||||||
YouTube.playlistOrAlbum(browseId)?.map {
|
YouTube.playlist(browseId)?.map {
|
||||||
it.next()
|
it.next()
|
||||||
}?.map { playlist ->
|
}?.map { playlist ->
|
||||||
playlist.copy(items = playlist.items?.filter { it.info.endpoint != null })
|
playlist.copy(items = playlist.items?.filter { it.info.endpoint != null })
|
||||||
|
|||||||
@@ -882,17 +882,23 @@ object YouTube {
|
|||||||
}.recoverIfCancelled()?.getOrNull()
|
}.recoverIfCancelled()?.getOrNull()
|
||||||
} ?: this
|
} ?: this
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
suspend fun withAudioSources(): Result<PlaylistOrAlbum>? {
|
suspend fun album(browseId: String): Result<PlaylistOrAlbum>? {
|
||||||
return url?.let { Url(it).parameters["list"] }?.let { playlistId ->
|
return playlistOrAlbum(browseId)?.map { album ->
|
||||||
playlistOrAlbum("VL$playlistId")?.map { playlist ->
|
album.url?.let { Url(it).parameters["list"] }?.let { playlistId ->
|
||||||
copy(items = playlist.items)
|
playlistOrAlbum("VL$playlistId")?.getOrNull()?.let { playlist ->
|
||||||
|
album.copy(items = playlist.items)
|
||||||
}
|
}
|
||||||
}
|
} ?: album
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun playlistOrAlbum(browseId: String): Result<PlaylistOrAlbum>? {
|
suspend fun playlist(browseId: String): Result<PlaylistOrAlbum>? {
|
||||||
|
return playlistOrAlbum(browseId)
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun playlistOrAlbum(browseId: String): Result<PlaylistOrAlbum>? {
|
||||||
return browse(browseId)?.map { body ->
|
return browse(browseId)?.map { body ->
|
||||||
PlaylistOrAlbum(
|
PlaylistOrAlbum(
|
||||||
title = body
|
title = body
|
||||||
|
|||||||
Reference in New Issue
Block a user