diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/data/AlbumDao.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/data/AlbumDao.kt index 8eccef40..e0b9a6cd 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/data/AlbumDao.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/data/AlbumDao.kt @@ -19,6 +19,12 @@ interface AlbumDao : GenericDao { @Query("SELECT * FROM albums") fun get(): List + /** + * Get album by id + */ + @Query("SELECT * FROM albums where id LIKE :albumId LIMIT 1") + fun get(albumId: String): Album + /** * Get albums by artist */ diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/data/TrackDao.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/data/TrackDao.kt index 7700d1a9..af2190bf 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/data/TrackDao.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/data/TrackDao.kt @@ -25,4 +25,10 @@ interface TrackDao : GenericDao { */ @Query("SELECT * FROM tracks WHERE albumId LIKE :id") fun byAlbum(id: String): List + + /** + * Get albums by artist + */ + @Query("SELECT * FROM tracks WHERE artistId LIKE :id") + fun byArtist(id: String): List } diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/Downloader.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/Downloader.kt index d7cad0e7..b46cb151 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/Downloader.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/Downloader.kt @@ -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() { diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/OfflineMusicService.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/OfflineMusicService.kt index 9af9f9ed..f4ddbbef 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/OfflineMusicService.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/OfflineMusicService.kt @@ -110,9 +110,6 @@ class OfflineMusicService : MusicService, KoinComponent { override fun getArtists(refresh: Boolean): List { 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 { - 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)