Do not return unused fields in DetailedSong

This commit is contained in:
vfsfitvnm 2022-08-03 21:09:08 +02:00
parent 194864bcb4
commit 61c8552ad0
12 changed files with 68 additions and 58 deletions

View file

@ -54,26 +54,32 @@ interface Database {
@Transaction @Transaction
@Query("SELECT * FROM Song WHERE totalPlayTimeMs > 0 ORDER BY ROWID ASC") @Query("SELECT * FROM Song WHERE totalPlayTimeMs > 0 ORDER BY ROWID ASC")
@RewriteQueriesToDropUnusedColumns
fun songsByRowIdAsc(): Flow<List<DetailedSong>> fun songsByRowIdAsc(): Flow<List<DetailedSong>>
@Transaction @Transaction
@Query("SELECT * FROM Song WHERE totalPlayTimeMs > 0 ORDER BY ROWID DESC") @Query("SELECT * FROM Song WHERE totalPlayTimeMs > 0 ORDER BY ROWID DESC")
@RewriteQueriesToDropUnusedColumns
fun songsByRowIdDesc(): Flow<List<DetailedSong>> fun songsByRowIdDesc(): Flow<List<DetailedSong>>
@Transaction @Transaction
@Query("SELECT * FROM Song WHERE totalPlayTimeMs > 0 ORDER BY title ASC") @Query("SELECT * FROM Song WHERE totalPlayTimeMs > 0 ORDER BY title ASC")
@RewriteQueriesToDropUnusedColumns
fun songsByTitleAsc(): Flow<List<DetailedSong>> fun songsByTitleAsc(): Flow<List<DetailedSong>>
@Transaction @Transaction
@Query("SELECT * FROM Song WHERE totalPlayTimeMs > 0 ORDER BY title DESC") @Query("SELECT * FROM Song WHERE totalPlayTimeMs > 0 ORDER BY title DESC")
@RewriteQueriesToDropUnusedColumns
fun songsByTitleDesc(): Flow<List<DetailedSong>> fun songsByTitleDesc(): Flow<List<DetailedSong>>
@Transaction @Transaction
@Query("SELECT * FROM Song WHERE totalPlayTimeMs > 0 ORDER BY totalPlayTimeMs ASC") @Query("SELECT * FROM Song WHERE totalPlayTimeMs > 0 ORDER BY totalPlayTimeMs ASC")
@RewriteQueriesToDropUnusedColumns
fun songsByPlayTimeAsc(): Flow<List<DetailedSong>> fun songsByPlayTimeAsc(): Flow<List<DetailedSong>>
@Transaction @Transaction
@Query("SELECT * FROM Song WHERE totalPlayTimeMs > 0 ORDER BY totalPlayTimeMs DESC") @Query("SELECT * FROM Song WHERE totalPlayTimeMs > 0 ORDER BY totalPlayTimeMs DESC")
@RewriteQueriesToDropUnusedColumns
fun songsByPlayTimeDesc(): Flow<List<DetailedSong>> fun songsByPlayTimeDesc(): Flow<List<DetailedSong>>
fun songs(sortBy: SongSortBy, sortOrder: SortOrder): Flow<List<DetailedSong>> { fun songs(sortBy: SongSortBy, sortOrder: SortOrder): Flow<List<DetailedSong>> {
@ -95,6 +101,7 @@ interface Database {
@Transaction @Transaction
@Query("SELECT * FROM Song WHERE likedAt IS NOT NULL ORDER BY likedAt DESC") @Query("SELECT * FROM Song WHERE likedAt IS NOT NULL ORDER BY likedAt DESC")
@RewriteQueriesToDropUnusedColumns
fun favorites(): Flow<List<DetailedSong>> fun favorites(): Flow<List<DetailedSong>>
@Query("SELECT * FROM QueuedMediaItem") @Query("SELECT * FROM QueuedMediaItem")

View file

@ -1,11 +1,16 @@
package it.vfsfitvnm.vimusic.models package it.vfsfitvnm.vimusic.models
import androidx.room.Embedded
import androidx.room.Junction import androidx.room.Junction
import androidx.room.Relation import androidx.room.Relation
open class DetailedSong( open class DetailedSong(
@Embedded val song: Song, val id: String,
val title: String,
val artistsText: String? = null,
val durationText: String,
val thumbnailUrl: String?,
val likedAt: Long? = null,
val totalPlayTimeMs: Long = 0,
@Relation( @Relation(
entity = SongAlbumMap::class, entity = SongAlbumMap::class,
entityColumn = "songId", entityColumn = "songId",
@ -24,4 +29,17 @@ open class DetailedSong(
) )
) )
val artists: List<Artist>? val artists: List<Artist>?
) ) {
val formattedTotalPlayTime: String
get() {
val seconds = totalPlayTimeMs / 1000
val hours = seconds / 3600
return when {
hours == 0L -> "${seconds / 60}m"
hours < 24L -> "${hours}h"
else -> "${hours / 24}d"
}
}
}

View file

@ -3,7 +3,13 @@ package it.vfsfitvnm.vimusic.models
import androidx.room.Relation import androidx.room.Relation
class DetailedSongWithContentLength( class DetailedSongWithContentLength(
song: Song, id: String,
title: String,
artistsText: String? = null,
durationText: String,
thumbnailUrl: String?,
likedAt: Long? = null,
totalPlayTimeMs: Long = 0,
albumId: String?, albumId: String?,
artists: List<Artist>?, artists: List<Artist>?,
@Relation( @Relation(
@ -13,4 +19,4 @@ class DetailedSongWithContentLength(
projection = ["contentLength"] projection = ["contentLength"]
) )
val contentLength: Long? val contentLength: Long?
) : DetailedSong(song, albumId, artists) ) : DetailedSong(id, title, artistsText, durationText, thumbnailUrl, likedAt, totalPlayTimeMs, albumId, artists)

View file

@ -15,19 +15,6 @@ data class Song(
val likedAt: Long? = null, val likedAt: Long? = null,
val totalPlayTimeMs: Long = 0 val totalPlayTimeMs: Long = 0
) { ) {
val formattedTotalPlayTime: String
get() {
val seconds = totalPlayTimeMs / 1000
val hours = seconds / 3600
return when {
hours == 0L -> "${seconds / 60}m"
hours < 24L -> "${hours}h"
else -> "${hours / 24}d"
}
}
fun toggleLike(): Song { fun toggleLike(): Song {
return copy( return copy(
likedAt = if (likedAt == null) System.currentTimeMillis() else null likedAt = if (likedAt == null) System.currentTimeMillis() else null

View file

@ -70,7 +70,7 @@ fun InFavoritesMediaItemMenu(
onDismiss = onDismiss, onDismiss = onDismiss,
onRemoveFromFavorites = { onRemoveFromFavorites = {
query { query {
Database.update(song.song.toggleLike()) Database.like(song.id, if (song.likedAt == null) System.currentTimeMillis() else null)
} }
}, },
modifier = modifier modifier = modifier
@ -94,15 +94,13 @@ fun InHistoryMediaItemMenu(
if (isHiding) { if (isHiding) {
ConfirmationDialog( ConfirmationDialog(
text = "Do you really hide this song? Its playback time and cache will be wiped.\nThis action is irreversible.", text = "Do you really hide this song? Its playback time and cache will be wiped.\nThis action is irreversible.",
onDismiss = { onDismiss = { isHiding = false },
isHiding = false
},
onConfirm = { onConfirm = {
(onDismiss ?: menuState::hide).invoke() (onDismiss ?: menuState::hide).invoke()
query { query {
// Not sure we can to this here // Not sure we can to this here
binder?.cache?.removeResource(song.song.id) binder?.cache?.removeResource(song.id)
Database.update(song.song.copy(totalPlayTimeMs = 0)) Database.incrementTotalPlayTimeMs(song.id, -song.totalPlayTimeMs)
} }
} }
) )
@ -111,9 +109,7 @@ fun InHistoryMediaItemMenu(
NonQueuedMediaItemMenu( NonQueuedMediaItemMenu(
mediaItem = song.asMediaItem, mediaItem = song.asMediaItem,
onDismiss = onDismiss, onDismiss = onDismiss,
onHideFromDatabase = { onHideFromDatabase = { isHiding = true },
isHiding = true
},
modifier = modifier modifier = modifier
) )
} }
@ -134,7 +130,7 @@ fun InPlaylistMediaItemMenu(
transaction { transaction {
Database.delete( Database.delete(
SongPlaylistMap( SongPlaylistMap(
songId = song.song.id, songId = song.id,
playlistId = playlistId, playlistId = playlistId,
position = positionInPlaylist position = positionInPlaylist
) )
@ -182,9 +178,7 @@ fun NonQueuedMediaItemMenu(
onPlayNext = { onPlayNext = {
binder?.player?.addNext(mediaItem) binder?.player?.addNext(mediaItem)
}, },
onEnqueue = { onEnqueue = { binder?.player?.enqueue(mediaItem) },
binder?.player?.enqueue(mediaItem)
},
onRemoveFromPlaylist = onRemoveFromPlaylist, onRemoveFromPlaylist = onRemoveFromPlaylist,
onHideFromDatabase = onHideFromDatabase, onHideFromDatabase = onHideFromDatabase,
onRemoveFromFavorites = onRemoveFromFavorites, onRemoveFromFavorites = onRemoveFromFavorites,

View file

@ -251,7 +251,7 @@ fun AlbumScreen(browseId: String) {
songs.forEachIndexed { index, song -> songs.forEachIndexed { index, song ->
Database.insert( Database.insert(
SongPlaylistMap( SongPlaylistMap(
songId = song.song.id, songId = song.id,
playlistId = playlistId, playlistId = playlistId,
position = index position = index
) )
@ -320,13 +320,13 @@ fun AlbumScreen(browseId: String) {
itemsIndexed( itemsIndexed(
items = songs, items = songs,
key = { _, song -> song.song.id }, key = { _, song -> song.id },
contentType = { _, song -> song } contentType = { _, song -> song }
) { index, song -> ) { index, song ->
SongItem( SongItem(
title = song.song.title, title = song.title,
authors = song.song.artistsText ?: albumResult?.getOrNull()?.authorsText, authors = song.artistsText ?: albumResult?.getOrNull()?.authorsText,
durationText = song.song.durationText, durationText = song.durationText,
onClick = { onClick = {
binder?.stopRadio() binder?.stopRadio()
binder?.player?.forcePlayAtIndex( binder?.player?.forcePlayAtIndex(

View file

@ -247,7 +247,7 @@ fun ArtistScreen(browseId: String) {
itemsIndexed( itemsIndexed(
items = songs, items = songs,
key = { _, song -> song.song.id }, key = { _, song -> song.id },
contentType = { _, song -> song }, contentType = { _, song -> song },
) { index, song -> ) { index, song ->
SongItem( SongItem(

View file

@ -74,7 +74,7 @@ fun BuiltInPlaylistScreen(builtInPlaylist: BuiltInPlaylist) {
BuiltInPlaylist.Offline -> Database.songsWithContentLength().map { songs -> BuiltInPlaylist.Offline -> Database.songsWithContentLength().map { songs ->
songs.filter { song -> songs.filter { song ->
song.contentLength?.let { song.contentLength?.let {
binder?.cache?.isCached(song.song.id, 0, song.contentLength) binder?.cache?.isCached(song.id, 0, song.contentLength)
} ?: false } ?: false
} }
} }
@ -180,7 +180,7 @@ fun BuiltInPlaylistScreen(builtInPlaylist: BuiltInPlaylist) {
itemsIndexed( itemsIndexed(
items = songs, items = songs,
key = { _, song -> song.song.id }, key = { _, song -> song.id },
contentType = { _, song -> song }, contentType = { _, song -> song },
) { index, song -> ) { index, song ->
SongItem( SongItem(

View file

@ -625,9 +625,7 @@ fun HomeScreen() {
itemsIndexed( itemsIndexed(
items = songCollection, items = songCollection,
key = { _, song -> key = { _, song -> song.id },
song.song.id
},
contentType = { _, song -> song } contentType = { _, song -> song }
) { index, song -> ) { index, song ->
SongItem( SongItem(
@ -652,7 +650,7 @@ fun HomeScreen() {
.align(Alignment.BottomCenter) .align(Alignment.BottomCenter)
) { ) {
BasicText( BasicText(
text = song.song.formattedTotalPlayTime, text = song.formattedTotalPlayTime,
style = typography.xxs.semiBold.center.color(Color.White), style = typography.xxs.semiBold.center.color(Color.White),
maxLines = 2, maxLines = 2,
overflow = TextOverflow.Ellipsis, overflow = TextOverflow.Ellipsis,

View file

@ -242,7 +242,7 @@ fun LocalPlaylistScreen(playlistId: Long) {
itemsIndexed( itemsIndexed(
items = playlistWithSongs.songs, items = playlistWithSongs.songs,
key = { _, song -> song.song.id }, key = { _, song -> song.id },
contentType = { _, song -> song }, contentType = { _, song -> song },
) { index, song -> ) { index, song ->
SongItem( SongItem(
@ -301,7 +301,7 @@ fun LocalPlaylistScreen(playlistId: Long) {
Database.update( Database.update(
SongPlaylistMap( SongPlaylistMap(
songId = playlistWithSongs.songs[index].song.id, songId = playlistWithSongs.songs[index].id,
playlistId = playlistWithSongs.playlist.id, playlistId = playlistWithSongs.playlist.id,
position = reachedIndex position = reachedIndex
) )

View file

@ -83,10 +83,10 @@ fun SongItem(
trailingContent: (@Composable () -> Unit)? = null trailingContent: (@Composable () -> Unit)? = null
) { ) {
SongItem( SongItem(
thumbnailModel = song.song.thumbnailUrl?.thumbnail(thumbnailSize), thumbnailModel = song.thumbnailUrl?.thumbnail(thumbnailSize),
title = song.song.title, title = song.title,
authors = song.song.artistsText ?: "", authors = song.artistsText ?: "",
durationText = song.song.durationText, durationText = song.durationText,
menuContent = menuContent, menuContent = menuContent,
onClick = onClick, onClick = onClick,
onThumbnailContent = onThumbnailContent, onThumbnailContent = onThumbnailContent,

View file

@ -70,23 +70,23 @@ val DetailedSong.asMediaItem: MediaItem
get() = MediaItem.Builder() get() = MediaItem.Builder()
.setMediaMetadata( .setMediaMetadata(
MediaMetadata.Builder() MediaMetadata.Builder()
.setTitle(song.title) .setTitle(title)
.setArtist(song.artistsText) .setArtist(artistsText)
.setArtworkUri(song.thumbnailUrl?.toUri()) .setArtworkUri(thumbnailUrl?.toUri())
.setExtras( .setExtras(
bundleOf( bundleOf(
"videoId" to song.id, "videoId" to id,
"albumId" to albumId, "albumId" to albumId,
"artistNames" to artists?.map { it.name }, "artistNames" to artists?.map { it.name },
"artistIds" to artists?.map { it.id }, "artistIds" to artists?.map { it.id },
"durationText" to song.durationText "durationText" to durationText
) )
) )
.build() .build()
) )
.setMediaId(song.id) .setMediaId(id)
.setUri(song.id) .setUri(id)
.setCustomCacheKey(song.id) .setCustomCacheKey(id)
.build() .build()
fun YouTube.PlaylistOrAlbum.Item.toMediaItem( fun YouTube.PlaylistOrAlbum.Item.toMediaItem(
@ -130,4 +130,4 @@ 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()
} }