Improve offline support for Compilations

This commit is contained in:
tzugen 2022-07-06 14:55:19 +02:00
parent 78bfab3753
commit de0cb7713b
No known key found for this signature in database
GPG Key ID: 61E9C34BC10EC930
4 changed files with 58 additions and 19 deletions

View File

@ -19,6 +19,12 @@ interface AlbumDao : GenericDao<Album> {
@Query("SELECT * FROM albums")
fun get(): List<Album>
/**
* Get album by id
*/
@Query("SELECT * FROM albums where id LIKE :albumId LIMIT 1")
fun get(albumId: String): Album
/**
* Get albums by artist
*/

View File

@ -25,4 +25,10 @@ interface TrackDao : GenericDao<Track> {
*/
@Query("SELECT * FROM tracks WHERE albumId LIKE :id")
fun byAlbum(id: String): List<Track>
/**
* Get albums by artist
*/
@Query("SELECT * FROM tracks WHERE artistId LIKE :id")
fun byArtist(id: String): List<Track>
}

View File

@ -14,6 +14,7 @@ import java.util.PriorityQueue
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
import org.moire.ultrasonic.data.ActiveServerProvider
import org.moire.ultrasonic.data.MetaDatabase
import org.moire.ultrasonic.domain.Artist
import org.moire.ultrasonic.domain.Track
import org.moire.ultrasonic.playback.LegacyPlaylistManager
@ -402,6 +403,14 @@ class Downloader(
downloadFile.completeFile
)
}
// Hidden feature: If track is toggled between pinned/saved, refresh the metadata..
try {
downloadFile.track.cacheMetadata()
} catch (ignore: Exception) {
Timber.w(ignore)
}
downloadFile.status.postValue(newStatus)
return
}
@ -518,7 +527,29 @@ class Downloader(
val onlineDB = activeServerProvider.getActiveMetaDatabase()
val offlineDB = activeServerProvider.offlineMetaDatabase
var artist: Artist? = onlineDB.artistDao().get(artistId!!)
cacheArtist(onlineDB, offlineDB, artistId!!)
// Now cache the album
if (albumId?.isNotEmpty() == true) {
// This is a cached call
val albums = musicService.getAlbumsOfArtist(artistId!!, null, false)
val album = albums.find { it.id == albumId }
if (album != null) {
offlineDB.albumDao().insert(album)
// If the album is a Compilation, also cache the Album artist
if (album.artistId != null && album.artistId != artistId)
cacheArtist(onlineDB, offlineDB, album.artistId!!)
}
}
// Now cache the track data
offlineDB.trackDao().insert(this)
}
private fun cacheArtist(onlineDB: MetaDatabase, offlineDB: MetaDatabase, artistId: String) {
var artist: Artist? = onlineDB.artistDao().get(artistId)
// If we are downloading a new album, and the user has not visited the Artists list
// recently, then the artist won't be in the database.
@ -533,20 +564,6 @@ class Downloader(
if (artist != null) {
offlineDB.artistDao().insert(artist)
}
// Now cache the album
if (albumId?.isNotEmpty() == true) {
// This is a cached call
val albums = musicService.getAlbumsOfArtist(artistId!!, null, false)
val album = albums.find { it.id == albumId }
if (album != null) {
offlineDB.albumDao().insert(album)
}
}
// Now cache the track data
offlineDB.trackDao().insert(this)
}
private fun downloadAndSaveCoverArt() {

View File

@ -110,9 +110,6 @@ class OfflineMusicService : MusicService, KoinComponent {
override fun getArtists(refresh: Boolean): List<Artist> {
val result = cachedArtists.get()
if (result.isEmpty()) {
// use indexes?
}
return result
}
@ -472,7 +469,20 @@ class OfflineMusicService : MusicService, KoinComponent {
@Throws(Exception::class)
override fun getAlbumsOfArtist(id: String, name: String?, refresh: Boolean):
List<Album> {
return cachedAlbums.byArtist(id)
val directAlbums = cachedAlbums.byArtist(id)
// The direct albums won't contain any compilations that the artist has participated in
// We need to fetch the tracks of the artist and then gather the compilation albums from that.
val tracks = cachedTracks.byArtist(id)
val albumIds = tracks.map {
it.albumId
}.distinct().filterNotNull()
val compilationAlbums = albumIds.map {
cachedAlbums.get(it)
}
return directAlbums.plus(compilationAlbums).distinct()
}
@Throws(OfflineException::class)