Add AlbumDao, rename getArtist to getAlbumsOfArtist

This commit is contained in:
tzugen 2022-04-18 07:12:31 +02:00
parent 3445576dc9
commit 3a3bd10fdb
No known key found for this signature in database
GPG Key ID: 61E9C34BC10EC930
16 changed files with 676 additions and 49 deletions

View File

@ -1,8 +1,10 @@
package org.moire.ultrasonic.domain
import androidx.room.Entity
import androidx.room.PrimaryKey
import java.util.Date
@Entity(tableName = "albums")
data class Album(
@PrimaryKey override var id: String,
override var parent: String? = null,

View File

@ -0,0 +1,474 @@
{
"formatVersion": 1,
"database": {
"version": 2,
"identityHash": "b6ac795e7857eac4fed2dbbd01f80fb8",
"entities": [
{
"tableName": "artists",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `name` TEXT, `index` TEXT, `coverArt` TEXT, `albumCount` INTEGER, `closeness` INTEGER NOT NULL, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "index",
"columnName": "index",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "coverArt",
"columnName": "coverArt",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "albumCount",
"columnName": "albumCount",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "closeness",
"columnName": "closeness",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "albums",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `parent` TEXT, `album` TEXT, `title` TEXT, `name` TEXT, `discNumber` INTEGER, `coverArt` TEXT, `songCount` INTEGER, `created` INTEGER, `artist` TEXT, `artistId` TEXT, `duration` INTEGER, `year` INTEGER, `genre` TEXT, `starred` INTEGER NOT NULL, `path` TEXT, `closeness` INTEGER NOT NULL, `isDirectory` INTEGER NOT NULL, `isVideo` INTEGER NOT NULL, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "parent",
"columnName": "parent",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "album",
"columnName": "album",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "title",
"columnName": "title",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "discNumber",
"columnName": "discNumber",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "coverArt",
"columnName": "coverArt",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "songCount",
"columnName": "songCount",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "created",
"columnName": "created",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "artist",
"columnName": "artist",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "artistId",
"columnName": "artistId",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "duration",
"columnName": "duration",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "year",
"columnName": "year",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "genre",
"columnName": "genre",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "starred",
"columnName": "starred",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "path",
"columnName": "path",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "closeness",
"columnName": "closeness",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "isDirectory",
"columnName": "isDirectory",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "isVideo",
"columnName": "isVideo",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "tracks",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `parent` TEXT, `isDirectory` INTEGER NOT NULL, `title` TEXT, `album` TEXT, `albumId` TEXT, `artist` TEXT, `artistId` TEXT, `track` INTEGER, `year` INTEGER, `genre` TEXT, `contentType` TEXT, `suffix` TEXT, `transcodedContentType` TEXT, `transcodedSuffix` TEXT, `coverArt` TEXT, `size` INTEGER, `songCount` INTEGER, `duration` INTEGER, `bitRate` INTEGER, `path` TEXT, `isVideo` INTEGER NOT NULL, `starred` INTEGER NOT NULL, `discNumber` INTEGER, `type` TEXT, `created` INTEGER, `closeness` INTEGER NOT NULL, `bookmarkPosition` INTEGER NOT NULL, `userRating` INTEGER, `averageRating` REAL, `name` TEXT, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "parent",
"columnName": "parent",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "isDirectory",
"columnName": "isDirectory",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "title",
"columnName": "title",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "album",
"columnName": "album",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "albumId",
"columnName": "albumId",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "artist",
"columnName": "artist",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "artistId",
"columnName": "artistId",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "track",
"columnName": "track",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "year",
"columnName": "year",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "genre",
"columnName": "genre",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "contentType",
"columnName": "contentType",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "suffix",
"columnName": "suffix",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "transcodedContentType",
"columnName": "transcodedContentType",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "transcodedSuffix",
"columnName": "transcodedSuffix",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "coverArt",
"columnName": "coverArt",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "size",
"columnName": "size",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "songCount",
"columnName": "songCount",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "duration",
"columnName": "duration",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "bitRate",
"columnName": "bitRate",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "path",
"columnName": "path",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "isVideo",
"columnName": "isVideo",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "starred",
"columnName": "starred",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "discNumber",
"columnName": "discNumber",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "type",
"columnName": "type",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "created",
"columnName": "created",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "closeness",
"columnName": "closeness",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "bookmarkPosition",
"columnName": "bookmarkPosition",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "userRating",
"columnName": "userRating",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "averageRating",
"columnName": "averageRating",
"affinity": "REAL",
"notNull": false
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "indexes",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `name` TEXT, `index` TEXT, `coverArt` TEXT, `albumCount` INTEGER, `closeness` INTEGER NOT NULL, `musicFolderId` TEXT, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "index",
"columnName": "index",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "coverArt",
"columnName": "coverArt",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "albumCount",
"columnName": "albumCount",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "closeness",
"columnName": "closeness",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "musicFolderId",
"columnName": "musicFolderId",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "music_folders",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `name` TEXT NOT NULL, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'b6ac795e7857eac4fed2dbbd01f80fb8')"
]
}
}

View File

@ -19,6 +19,7 @@ import androidx.recyclerview.widget.RecyclerView
import com.drakeet.multitype.ItemViewBinder
import org.koin.core.component.KoinComponent
import org.moire.ultrasonic.R
import org.moire.ultrasonic.data.ActiveServerProvider
import org.moire.ultrasonic.domain.ArtistOrIndex
import org.moire.ultrasonic.domain.Identifiable
import org.moire.ultrasonic.imageloader.ImageLoader
@ -57,7 +58,7 @@ class ArtistRowBinder(
holder.coverArtId = item.coverArt
if (Settings.shouldShowArtistPicture) {
if (showArtistPicture()) {
holder.coverArt.visibility = View.VISIBLE
val key = FileUtil.getArtistArtKey(item.name, false)
imageLoader.loadImage(
@ -108,6 +109,12 @@ class ArtistRowBinder(
return section.toString()
}
private fun showArtistPicture(): Boolean {
val isOffline = ActiveServerProvider.isOffline()
val shouldShowArtistPicture = Settings.shouldShowArtistPicture
return (!isOffline && shouldShowArtistPicture) || Settings.useId3TagsOffline
}
/**
* Creates an instance of our ViewHolder class
*/

View File

@ -110,7 +110,14 @@ class ActiveServerProvider(
Timber.i("Switching to new database, id:$activeServer")
cachedServerId = activeServer
return buildDatabase(cachedServerId)
return Room.databaseBuilder(
UApp.applicationContext(),
MetaDatabase::class.java,
METADATA_DB + cachedServerId
)
.addMigrations(META_MIGRATION_2_1)
.fallbackToDestructiveMigrationOnDowngrade()
.build()
}
val offlineMetaDatabase: MetaDatabase by lazy {

View File

@ -0,0 +1,68 @@
package org.moire.ultrasonic.data
import androidx.room.Dao
import androidx.room.Query
import androidx.room.Transaction
import org.moire.ultrasonic.domain.Album
@Dao
interface AlbumDao : GenericDao<Album> {
/**
* Clear the whole database
*/
@Query("DELETE FROM albums")
fun clear()
/**
* Get all albums
*/
@Query("SELECT * FROM albums")
fun get(): List<Album>
/**
* Get albums by artist
*/
@Query("SELECT * FROM albums WHERE artistId LIKE :id")
fun byArtist(id: String): List<Album>
/**
* Clear albums by artist
*/
@Query("DELETE FROM albums WHERE artistId LIKE :id")
fun clearByArtist(id: String)
/**
* FIXME: Make generic
* Upserts (insert or update) an object to the database
*
* @param obj the object to upsert
*/
@Transaction
@JvmSuppressWildcards
fun upsert(obj: Album) {
val id = insertIgnoring(obj)
if (id == -1L) {
update(obj)
}
}
/**
* Upserts (insert or update) a list of objects
*
* @param objList the object to be upserted
*/
@Transaction
@JvmSuppressWildcards
fun upsert(objList: List<Album>) {
val insertResult = insertIgnoring(objList)
val updateList: MutableList<Album> = ArrayList()
for (i in insertResult.indices) {
if (insertResult[i] == -1L) {
updateList.add(objList[i])
}
}
if (updateList.isNotEmpty()) {
update(updateList)
}
}
}

View File

@ -43,5 +43,5 @@ interface ArtistsDao {
* Get artist by id
*/
@Query("SELECT * FROM artists WHERE id LIKE :id")
fun get(id: String): Artist
fun get(id: String): Artist?
}

View File

@ -1,7 +1,14 @@
package org.moire.ultrasonic.data
import androidx.room.AutoMigration
import androidx.room.Database
import androidx.room.RoomDatabase
import androidx.room.TypeConverter
import androidx.room.TypeConverters
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
import org.moire.ultrasonic.domain.Album
import java.util.Date
import org.moire.ultrasonic.domain.Artist
import org.moire.ultrasonic.domain.Index
import org.moire.ultrasonic.domain.MusicFolder
@ -11,14 +18,41 @@ import org.moire.ultrasonic.domain.MusicFolder
*/
@Database(
entities = [Artist::class, Index::class, MusicFolder::class],
version = 1,
entities = [Artist::class, Album::class, Index::class, MusicFolder::class],
version = 2,
autoMigrations = [
AutoMigration(from = 1, to = 2)
],
exportSchema = true
)
@TypeConverters(Converters::class)
abstract class MetaDatabase : RoomDatabase() {
abstract fun artistsDao(): ArtistsDao
abstract fun albumDao(): AlbumDao
abstract fun musicFoldersDao(): MusicFoldersDao
abstract fun indexDao(): IndexDao
}
class Converters {
@TypeConverter
fun fromTimestamp(value: Long?): Date? {
return value?.let { Date(it) }
}
@TypeConverter
fun dateToTimestamp(date: Date?): Long? {
return date?.time
}
}
// FIXME: Check if correct
val META_MIGRATION_2_1: Migration = object : Migration(2, 1) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL(
"DROP TABLE ServerSetting"
)
}
}

View File

@ -39,7 +39,7 @@ class AlbumListModel(application: Application) : GenericListModel(application) {
id: String,
name: String?
) {
list.postValue(musicService.getArtist(id, name, refresh))
list.postValue(musicService.getAlbumsOfArtist(id, name, refresh))
}
override fun load(

View File

@ -26,6 +26,7 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import java.text.Collator
import org.moire.ultrasonic.domain.ArtistOrIndex
import org.moire.ultrasonic.service.MusicService
import org.moire.ultrasonic.util.Settings
/**
* Provides ViewModel which contains the list of available Artists
@ -58,7 +59,7 @@ class ArtistListModel(application: Application) : GenericListModel(application)
val result: List<ArtistOrIndex>
if (!isOffline && useId3Tags) {
if (!isOffline && useId3Tags || Settings.useId3TagsOffline) {
result = musicService.getArtists(refresh)
} else {
result = musicService.getIndexes(musicFolderId, refresh)

View File

@ -635,7 +635,7 @@ class AutoMediaBrowserCallback(var player: Player, val libraryService: MediaLibr
return serviceScope.future {
val albums = if (!isOffline && useId3Tags) {
callWithErrorHandling { musicService.getArtist(id, name, false) }
callWithErrorHandling { musicService.getAlbumsOfArtist(id, name, false) }
} else {
callWithErrorHandling {
musicService.getMusicDirectory(id, name, false).getAlbums()

View File

@ -43,7 +43,6 @@ class CachedMusicService(private val musicService: MusicService) : MusicService,
// Old style TimeLimitedCache
private val cachedMusicDirectories: LRUCache<String, TimeLimitedCache<MusicDirectory?>>
private val cachedArtist: LRUCache<String, TimeLimitedCache<List<Album>>>
private val cachedAlbum: LRUCache<String, TimeLimitedCache<MusicDirectory?>>
private val cachedUserInfo: LRUCache<String, TimeLimitedCache<UserInfo?>>
private val cachedLicenseValid = TimeLimitedCache<Boolean>(120, TimeUnit.SECONDS)
@ -54,6 +53,7 @@ class CachedMusicService(private val musicService: MusicService) : MusicService,
// New Room Database
private var cachedArtists = metaDatabase.artistsDao()
private var cachedAlbums = metaDatabase.albumDao()
private var cachedIndexes = metaDatabase.indexDao()
private val cachedMusicFolders = metaDatabase.musicFoldersDao()
@ -103,10 +103,10 @@ class CachedMusicService(private val musicService: MusicService) : MusicService,
var indexes: List<Index>
if (musicFolderId == null) {
indexes = cachedIndexes.get()
indexes = if (musicFolderId == null) {
cachedIndexes.get()
} else {
indexes = cachedIndexes.get(musicFolderId)
cachedIndexes.get(musicFolderId)
}
if (indexes.isEmpty()) {
@ -117,17 +117,40 @@ class CachedMusicService(private val musicService: MusicService) : MusicService,
return indexes
}
// FIXME why commented?
// @Throws(Exception::class)
// override fun getArtist(id: String, refresh: Boolean): Artist? {
//
// // Check if we have a cache hit
// var result = cachedArtists.get(id)
//
// if (result == null || refresh) {
// musicService.getArtists(refresh = true)
// }
// //var result = cachedArtists.get()
//
// if (result.isEmpty()) {
// result = getArtists(refresh)
// // FIXME
// // cachedAlbums.clear()
// cachedArtists.set(result)
// }
// return result
// }
//
@Throws(Exception::class)
override fun getArtists(refresh: Boolean): List<Artist> {
checkSettingsChanged()
if (refresh) {
cachedArtists.clear()
}
// FIXME unnecessary check
var result = cachedArtists.get()
if (result.isEmpty()) {
result = musicService.getArtists(refresh)
cachedArtist.clear()
// FIXME
// cachedAlbums.clear()
cachedArtists.set(result)
}
return result
@ -150,20 +173,24 @@ class CachedMusicService(private val musicService: MusicService) : MusicService,
}
@Throws(Exception::class)
override fun getArtist(id: String, name: String?, refresh: Boolean):
override fun getAlbumsOfArtist(id: String, name: String?, refresh: Boolean):
List<Album> {
checkSettingsChanged()
var cache = if (refresh) null else cachedArtist[id]
var dir = cache?.get()
if (dir == null) {
dir = musicService.getArtist(id, name, refresh)
cache = TimeLimitedCache(
Settings.directoryCacheTime.toLong(), TimeUnit.SECONDS
)
cache.set(dir)
cachedArtist.put(id, cache)
var result: List<Album>
result = if (refresh) {
cachedAlbums.clearByArtist(id)
listOf()
} else {
cachedAlbums.byArtist(id)
}
return dir
if (result.isEmpty()) {
result = musicService.getAlbumsOfArtist(id, name, refresh)
cachedAlbums.upsert(result)
}
return result
}
@Throws(Exception::class)
@ -327,6 +354,7 @@ class CachedMusicService(private val musicService: MusicService) : MusicService,
// Switch database
metaDatabase = activeServerProvider.getActiveMetaDatabase()
cachedArtists = metaDatabase.artistsDao()
cachedAlbums = metaDatabase.albumDao()
cachedIndexes = metaDatabase.indexDao()
// Clear in memory caches
@ -335,7 +363,6 @@ class CachedMusicService(private val musicService: MusicService) : MusicService,
cachedPlaylists.clear()
cachedGenres.clear()
cachedAlbum.clear()
cachedArtist.clear()
cachedUserInfo.clear()
// Set the cache keys
@ -472,7 +499,6 @@ class CachedMusicService(private val musicService: MusicService) : MusicService,
init {
cachedMusicDirectories = LRUCache(MUSIC_DIR_CACHE_SIZE)
cachedArtist = LRUCache(MUSIC_DIR_CACHE_SIZE)
cachedAlbum = LRUCache(MUSIC_DIR_CACHE_SIZE)
cachedUserInfo = LRUCache(MUSIC_DIR_CACHE_SIZE)
}

View File

@ -59,7 +59,7 @@ interface MusicService {
fun getMusicDirectory(id: String, name: String?, refresh: Boolean): MusicDirectory
@Throws(Exception::class)
fun getArtist(id: String, name: String?, refresh: Boolean): List<Album>
fun getAlbumsOfArtist(id: String, name: String?, refresh: Boolean): List<Album>
@Throws(Exception::class)
fun getAlbum(id: String, name: String?, refresh: Boolean): MusicDirectory

View File

@ -23,6 +23,7 @@ import java.util.regex.Pattern
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.Album
import org.moire.ultrasonic.domain.Artist
import org.moire.ultrasonic.domain.ArtistOrIndex
@ -52,6 +53,14 @@ import timber.log.Timber
class OfflineMusicService : MusicService, KoinComponent {
private val activeServerProvider: ActiveServerProvider by inject()
private var metaDatabase: MetaDatabase = activeServerProvider.getActiveMetaDatabase()
// New Room Database
private var cachedArtists = metaDatabase.artistsDao()
private var cachedAlbums = metaDatabase.albumDao()
private var cachedIndexes = metaDatabase.indexDao()
private val cachedMusicFolders = metaDatabase.musicFoldersDao()
override fun getIndexes(musicFolderId: String?, refresh: Boolean): List<Index> {
val indexes: MutableList<Index> = ArrayList()
val root = FileUtil.musicDirectory
@ -97,6 +106,16 @@ class OfflineMusicService : MusicService, KoinComponent {
return indexes
}
@Throws(OfflineException::class)
override fun getArtists(refresh: Boolean): List<Artist> {
var result = cachedArtists.get()
if (result.isEmpty()) {
// use indexes?
}
return result
}
/*
* Especially when dealing with indexes, this method can return Albums, Entries or a mix of both!
*/
@ -450,15 +469,11 @@ class OfflineMusicService : MusicService, KoinComponent {
override fun isLicenseValid(): Boolean = true
@Throws(OfflineException::class)
override fun getArtists(refresh: Boolean): List<Artist> {
throw OfflineException("getArtists isn't available in offline mode")
}
@Throws(OfflineException::class)
override fun getArtist(id: String, name: String?, refresh: Boolean):
@Throws(Exception::class)
override fun getAlbumsOfArtist(id: String, name: String?, refresh: Boolean):
List<Album> {
throw OfflineException("getArtist isn't available in offline mode")
// FIXME: Add fallback?
return cachedAlbums.byArtist(id)
}
@Throws(OfflineException::class)

View File

@ -141,7 +141,7 @@ open class RESTMusicService(
}
@Throws(Exception::class)
override fun getArtist(
override fun getAlbumsOfArtist(
id: String,
name: String?,
refresh: Boolean

View File

@ -269,7 +269,7 @@ class DownloadHandler(
return
}
val musicService = getMusicService()
val artist = musicService.getArtist(id, "", false)
val artist = musicService.getAlbumsOfArtist(id, "", false)
for ((id1) in artist) {
val albumDirectory = musicService.getAlbum(
id1,

View File

@ -13,7 +13,6 @@ import androidx.preference.PreferenceManager
import java.util.regex.Pattern
import org.moire.ultrasonic.R
import org.moire.ultrasonic.app.UApp
import org.moire.ultrasonic.data.ActiveServerProvider
/**
* Contains convenience functions for reading and writing preferences
@ -161,8 +160,7 @@ object Settings {
by BooleanSetting(Constants.PREFERENCES_KEY_SHOW_NOW_PLAYING_DETAILS, false)
@JvmStatic
var shouldUseId3Tags
by BooleanSetting(Constants.PREFERENCES_KEY_ID3_TAGS, false)
var shouldUseId3Tags by BooleanSetting(Constants.PREFERENCES_KEY_ID3_TAGS, false)
var activeServer by IntSetting(Constants.PREFERENCES_KEY_SERVER_INSTANCE, -1)
@ -170,15 +168,8 @@ object Settings {
var firstRunExecuted by BooleanSetting(Constants.PREFERENCES_KEY_FIRST_RUN_EXECUTED, false)
val shouldShowArtistPicture: Boolean
get() {
val preferences = preferences
val isOffline = ActiveServerProvider.isOffline()
val isId3Enabled = preferences.getBoolean(Constants.PREFERENCES_KEY_ID3_TAGS, false)
val shouldShowArtistPicture =
preferences.getBoolean(Constants.PREFERENCES_KEY_SHOW_ARTIST_PICTURE, false)
return !isOffline && isId3Enabled && shouldShowArtistPicture
}
val shouldShowArtistPicture
by BooleanSetting(Constants.PREFERENCES_KEY_SHOW_ARTIST_PICTURE, false)
@JvmStatic
var chatRefreshInterval by StringIntSetting(
@ -253,6 +244,8 @@ object Settings {
var useHwOffload by BooleanSetting(Constants.PREFERENCES_KEY_HARDWARE_OFFLOAD, false)
var useId3TagsOffline = true
// TODO: Remove in December 2022
fun migrateFeatureStorage() {
val sp = appContext.getSharedPreferences("feature_flags", Context.MODE_PRIVATE)