From 8490f7115d3fb97d5e153f0bc2a2f24c20e5a993 Mon Sep 17 00:00:00 2001 From: tzugen Date: Mon, 18 Apr 2022 07:31:06 +0200 Subject: [PATCH] Add Offline support for tracks --- .../org/moire/ultrasonic/domain/Track.kt | 2 +- .../ultrasonic/data/ActiveServerProvider.kt | 21 +++++++------------ .../org/moire/ultrasonic/data/AlbumDao.kt | 2 +- .../data/{ArtistsDao.kt => ArtistDao.kt} | 2 +- .../org/moire/ultrasonic/data/BasicDaos.kt | 1 + .../org/moire/ultrasonic/data/MetaDatabase.kt | 18 +++++++++------- .../org/moire/ultrasonic/data/TrackDao.kt | 15 +++++++------ .../fragment/TrackCollectionFragment.kt | 2 +- .../ultrasonic/service/CachedMusicService.kt | 5 +++-- .../ultrasonic/service/OfflineMusicService.kt | 16 +++++++++++--- .../org/moire/ultrasonic/util/Constants.kt | 1 + .../org/moire/ultrasonic/util/Settings.kt | 6 ++++-- ultrasonic/src/main/res/values/strings.xml | 2 ++ ultrasonic/src/main/res/xml/settings.xml | 6 ++++++ 14 files changed, 61 insertions(+), 38 deletions(-) rename ultrasonic/src/main/kotlin/org/moire/ultrasonic/data/{ArtistsDao.kt => ArtistDao.kt} (97%) diff --git a/core/domain/src/main/kotlin/org/moire/ultrasonic/domain/Track.kt b/core/domain/src/main/kotlin/org/moire/ultrasonic/domain/Track.kt index 3a57296f..4c737bec 100644 --- a/core/domain/src/main/kotlin/org/moire/ultrasonic/domain/Track.kt +++ b/core/domain/src/main/kotlin/org/moire/ultrasonic/domain/Track.kt @@ -5,7 +5,7 @@ import androidx.room.PrimaryKey import java.io.Serializable import java.util.Date -@Entity +@Entity(tableName = "tracks") data class Track( @PrimaryKey override var id: String, override var parent: String? = null, diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/data/ActiveServerProvider.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/data/ActiveServerProvider.kt index 54dba5dd..2483a7e8 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/data/ActiveServerProvider.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/data/ActiveServerProvider.kt @@ -24,6 +24,7 @@ class ActiveServerProvider( private val repository: ServerSettingDao ) : CoroutineScope by CoroutineScope(Dispatchers.IO) { private var cachedServer: ServerSetting? = null + // FIXME cach never set private var cachedDatabase: MetaDatabase? = null private var cachedServerId: Int? = null @@ -110,27 +111,21 @@ class ActiveServerProvider( Timber.i("Switching to new database, id:$activeServer") cachedServerId = activeServer - return Room.databaseBuilder( - UApp.applicationContext(), - MetaDatabase::class.java, - METADATA_DB + cachedServerId - ) - .addMigrations(META_MIGRATION_2_1) - .fallbackToDestructiveMigrationOnDowngrade() - .build() + cachedDatabase = initDatabase(activeServer) + + return cachedDatabase!! } val offlineMetaDatabase: MetaDatabase by lazy { - buildDatabase(OFFLINE_DB_ID) + initDatabase(0) } - private fun buildDatabase(id: Int?): MetaDatabase { + private fun initDatabase(serverId: Int): MetaDatabase { return Room.databaseBuilder( UApp.applicationContext(), MetaDatabase::class.java, - METADATA_DB + id - ) - .fallbackToDestructiveMigration() + METADATA_DB + serverId + ).fallbackToDestructiveMigration() .build() } 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 59b5e7da..8eccef40 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/data/AlbumDao.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/data/AlbumDao.kt @@ -32,7 +32,7 @@ interface AlbumDao : GenericDao { fun clearByArtist(id: String) /** - * FIXME: Make generic + * TODO: Make generic * Upserts (insert or update) an object to the database * * @param obj the object to upsert diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/data/ArtistsDao.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/data/ArtistDao.kt similarity index 97% rename from ultrasonic/src/main/kotlin/org/moire/ultrasonic/data/ArtistsDao.kt rename to ultrasonic/src/main/kotlin/org/moire/ultrasonic/data/ArtistDao.kt index 61571285..9b2dc395 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/data/ArtistsDao.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/data/ArtistDao.kt @@ -7,7 +7,7 @@ import androidx.room.Query import org.moire.ultrasonic.domain.Artist @Dao -interface ArtistsDao { +interface ArtistDao { /** * Insert a list in the database. If the item already exists, replace it. * diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/data/BasicDaos.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/data/BasicDaos.kt index 1f3e77f5..9078f911 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/data/BasicDaos.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/data/BasicDaos.kt @@ -53,6 +53,7 @@ interface IndexDao : GenericDao { fun get(musicFolderId: String): List /** + * TODO: Make generic * Upserts (insert or update) an object to the database * * @param obj the object to upsert diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/data/MetaDatabase.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/data/MetaDatabase.kt index afbf8e76..dc377118 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/data/MetaDatabase.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/data/MetaDatabase.kt @@ -1,33 +1,36 @@ 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.Album import org.moire.ultrasonic.domain.Artist import org.moire.ultrasonic.domain.Index import org.moire.ultrasonic.domain.MusicFolder +import org.moire.ultrasonic.domain.Track /** * This database is used to store and cache the ID3 metadata */ @Database( - entities = [Artist::class, Album::class, Index::class, MusicFolder::class], - version = 2, - autoMigrations = [ - AutoMigration(from = 1, to = 2) + entities = [ + Artist::class, + Album::class, + Track::class, + Index::class, + MusicFolder::class ], + version = 2, exportSchema = true ) @TypeConverters(Converters::class) abstract class MetaDatabase : RoomDatabase() { - abstract fun artistsDao(): ArtistsDao + abstract fun artistDao(): ArtistDao abstract fun albumDao(): AlbumDao @@ -50,7 +53,6 @@ class Converters { } } -// FIXME: Check if correct val META_MIGRATION_2_1: Migration = object : Migration(2, 1) { override fun migrate(database: SupportSQLiteDatabase) { database.execSQL( 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 662ba1b9..7700d1a9 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/data/TrackDao.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/data/TrackDao.kt @@ -1,9 +1,13 @@ package org.moire.ultrasonic.data +import androidx.room.Dao +import androidx.room.Entity import androidx.room.Query -import org.moire.ultrasonic.domain.MusicDirectory +import org.moire.ultrasonic.domain.Track -interface TrackDao { +@Dao +@Entity(tableName = "tracks") +interface TrackDao : GenericDao { /** * Clear the whole database */ @@ -14,12 +18,11 @@ interface TrackDao { * Get all albums */ @Query("SELECT * FROM tracks") - fun get(): List + fun get(): List /** * Get albums by artist */ @Query("SELECT * FROM tracks WHERE albumId LIKE :id") - fun byAlbum(id: String): List - -} \ No newline at end of file + fun byAlbum(id: String): List +} diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/TrackCollectionFragment.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/TrackCollectionFragment.kt index 3c9fcb39..74b00ae5 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/TrackCollectionFragment.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/TrackCollectionFragment.kt @@ -600,7 +600,7 @@ open class TrackCollectionFragment : MultiListFragment() { listModel.getRandom(albumListSize) } else { setTitle(name) - if (!isOffline() && Settings.shouldUseId3Tags) { + if (!isOffline() && Settings.shouldUseId3Tags || Settings.useId3TagsOffline) { if (isAlbum) { listModel.getAlbum(refresh2, id!!, name) } else { diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/CachedMusicService.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/CachedMusicService.kt index cf8e432b..9b2775dd 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/CachedMusicService.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/CachedMusicService.kt @@ -52,8 +52,9 @@ class CachedMusicService(private val musicService: MusicService) : MusicService, private val cachedGenres = TimeLimitedCache>(10 * 3600, TimeUnit.SECONDS) // New Room Database - private var cachedArtists = metaDatabase.artistsDao() + private var cachedArtists = metaDatabase.artistDao() private var cachedAlbums = metaDatabase.albumDao() + private var cachedTracks = metaDatabase.trackDao() private var cachedIndexes = metaDatabase.indexDao() private val cachedMusicFolders = metaDatabase.musicFoldersDao() @@ -353,7 +354,7 @@ class CachedMusicService(private val musicService: MusicService) : MusicService, if (!Util.equals(newUrl, restUrl) || !Util.equals(cachedMusicFolderId, newFolderId)) { // Switch database metaDatabase = activeServerProvider.getActiveMetaDatabase() - cachedArtists = metaDatabase.artistsDao() + cachedArtists = metaDatabase.artistDao() cachedAlbums = metaDatabase.albumDao() cachedIndexes = metaDatabase.indexDao() 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 3f0d00bf..11eaeb10 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/OfflineMusicService.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/OfflineMusicService.kt @@ -44,6 +44,7 @@ import org.moire.ultrasonic.domain.Track import org.moire.ultrasonic.domain.UserInfo import org.moire.ultrasonic.util.AbstractFile import org.moire.ultrasonic.util.Constants +import org.moire.ultrasonic.util.EntryByDiscAndTrackComparator import org.moire.ultrasonic.util.FileUtil import org.moire.ultrasonic.util.Storage import org.moire.ultrasonic.util.Util.safeClose @@ -56,8 +57,9 @@ class OfflineMusicService : MusicService, KoinComponent { private var metaDatabase: MetaDatabase = activeServerProvider.getActiveMetaDatabase() // New Room Database - private var cachedArtists = metaDatabase.artistsDao() + private var cachedArtists = metaDatabase.artistDao() private var cachedAlbums = metaDatabase.albumDao() + private var cachedTracks = metaDatabase.trackDao() private var cachedIndexes = metaDatabase.indexDao() private val cachedMusicFolders = metaDatabase.musicFoldersDao() @@ -108,7 +110,7 @@ class OfflineMusicService : MusicService, KoinComponent { @Throws(OfflineException::class) override fun getArtists(refresh: Boolean): List { - var result = cachedArtists.get() + val result = cachedArtists.get() if (result.isEmpty()) { // use indexes? @@ -478,7 +480,15 @@ class OfflineMusicService : MusicService, KoinComponent { @Throws(OfflineException::class) override fun getAlbum(id: String, name: String?, refresh: Boolean): MusicDirectory { - throw OfflineException("getAlbum isn't available in offline mode") + + val list = cachedTracks + .byAlbum(id) + .sortedWith(EntryByDiscAndTrackComparator()) + + var dir = MusicDirectory() + dir.addAll(list) + + return dir } @Throws(OfflineException::class) diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/Constants.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/Constants.kt index 75b349b4..9f44202b 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/Constants.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/Constants.kt @@ -86,6 +86,7 @@ object Constants { const val PREFERENCES_KEY_INCREMENT_TIME = "incrementTime" const val PREFERENCES_KEY_SHOW_NOW_PLAYING_DETAILS = "showNowPlayingDetails" const val PREFERENCES_KEY_ID3_TAGS = "useId3Tags" + const val PREFERENCES_KEY_ID3_TAGS_OFFLINE = "useId3TagsOffline" const val PREFERENCES_KEY_SHOW_ARTIST_PICTURE = "showArtistPicture" const val PREFERENCES_KEY_CHAT_REFRESH_INTERVAL = "chatRefreshInterval" const val PREFERENCES_KEY_DIRECTORY_CACHE_TIME = "directoryCacheTime" diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/Settings.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/Settings.kt index 152d7ead..ce559913 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/Settings.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/Settings.kt @@ -130,6 +130,7 @@ object Settings { @JvmStatic var mediaButtonsEnabled by BooleanSetting(Constants.PREFERENCES_KEY_MEDIA_BUTTONS, true) + var resumePlayOnHeadphonePlug by BooleanSetting(R.string.setting_keys_resume_play_on_headphones_plug, true) @@ -162,6 +163,9 @@ object Settings { @JvmStatic var shouldUseId3Tags by BooleanSetting(Constants.PREFERENCES_KEY_ID3_TAGS, false) + @JvmStatic + var useId3TagsOffline by BooleanSetting(Constants.PREFERENCES_KEY_ID3_TAGS_OFFLINE, false) + var activeServer by IntSetting(Constants.PREFERENCES_KEY_SERVER_INSTANCE, -1) var serverScaling by BooleanSetting(Constants.PREFERENCES_KEY_SERVER_SCALING, false) @@ -244,8 +248,6 @@ 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) diff --git a/ultrasonic/src/main/res/values/strings.xml b/ultrasonic/src/main/res/values/strings.xml index 4ace333f..b4e81c76 100644 --- a/ultrasonic/src/main/res/values/strings.xml +++ b/ultrasonic/src/main/res/values/strings.xml @@ -316,6 +316,8 @@ Show details in Now Playing Browse Using ID3 Tags Use ID3 tag methods instead of file system based methods + Use ID3 method also when offline + (Experimental) Show artist picture in artist list Displays the artist picture in the artist list if available Video diff --git a/ultrasonic/src/main/res/xml/settings.xml b/ultrasonic/src/main/res/xml/settings.xml index 04f81008..8cd5fea1 100644 --- a/ultrasonic/src/main/res/xml/settings.xml +++ b/ultrasonic/src/main/res/xml/settings.xml @@ -59,6 +59,12 @@ a:summary="@string/settings.use_id3_summary" a:title="@string/settings.use_id3" app:iconSpaceReserved="false"/> +