From 4033a791a79c2984eee7a7c9200a8984c7fd8430 Mon Sep 17 00:00:00 2001 From: Alexander Capehart Date: Mon, 20 Mar 2023 11:32:13 -0600 Subject: [PATCH] playlist: consider playlists music Consider playlists music rather than an extension of music. This also sets up the basics of a playlist datbaase. --- .../oxycblt/auxio/detail/DetailViewModel.kt | 2 +- .../auxio/detail/GenreDetailFragment.kt | 8 +- .../org/oxycblt/auxio/home/HomeFragment.kt | 2 +- .../org/oxycblt/auxio/home/HomeViewModel.kt | 2 +- .../list/selection/SelectionViewModel.kt | 3 +- .../java/org/oxycblt/auxio/music/Music.kt | 16 ++++ .../oxycblt/auxio/music/MusicRepository.kt | 2 +- .../auxio/music/cache/CacheDatabase.kt | 2 +- .../auxio/music/cache/CacheRepository.kt | 2 +- .../auxio/music/{model => library}/Library.kt | 2 +- .../music/{model => library}/MusicImpl.kt | 2 +- .../music/{model => library}/RawMusic.kt | 2 +- .../auxio/music/metadata/TagExtractor.kt | 2 +- .../oxycblt/auxio/music/metadata/TagWorker.kt | 2 +- .../playlist/PlaylistDatabase.kt} | 24 ++++-- .../auxio/music/playlist/PlaylistImpl.kt | 33 ++++++++ .../{ => music}/playlist/PlaylistModule.kt | 21 +++-- .../auxio/music/playlist/RawPlaylist.kt | 41 ++++++++++ .../music/storage/MediaStoreExtractor.kt | 2 +- .../org/oxycblt/auxio/music/system/Indexer.kt | 4 +- .../oxycblt/auxio/picker/PickerViewModel.kt | 2 +- .../auxio/playback/PlaybackViewModel.kt | 2 + .../playback/persist/PersistenceDatabase.kt | 11 +-- .../playback/persist/PersistenceRepository.kt | 2 +- .../auxio/playback/system/PlaybackService.kt | 2 +- .../auxio/playlist/PlaylistRepository.kt | 77 ------------------- .../oxycblt/auxio/search/SearchFragment.kt | 8 +- .../oxycblt/auxio/search/SearchViewModel.kt | 2 +- .../auxio/music/MusicRepositoryTest.kt | 4 +- .../oxycblt/auxio/music/MusicViewModelTest.kt | 2 +- .../music/{model => library}/FakeLibrary.kt | 2 +- .../music/{model => library}/RawMusicTest.kt | 2 +- 32 files changed, 154 insertions(+), 136 deletions(-) rename app/src/main/java/org/oxycblt/auxio/music/{model => library}/Library.kt (99%) rename app/src/main/java/org/oxycblt/auxio/music/{model => library}/MusicImpl.kt (99%) rename app/src/main/java/org/oxycblt/auxio/music/{model => library}/RawMusic.kt (99%) rename app/src/main/java/org/oxycblt/auxio/{playlist/Playlist.kt => music/playlist/PlaylistDatabase.kt} (55%) create mode 100644 app/src/main/java/org/oxycblt/auxio/music/playlist/PlaylistImpl.kt rename app/src/main/java/org/oxycblt/auxio/{ => music}/playlist/PlaylistModule.kt (57%) create mode 100644 app/src/main/java/org/oxycblt/auxio/music/playlist/RawPlaylist.kt delete mode 100644 app/src/main/java/org/oxycblt/auxio/playlist/PlaylistRepository.kt rename app/src/test/java/org/oxycblt/auxio/music/{model => library}/FakeLibrary.kt (97%) rename app/src/test/java/org/oxycblt/auxio/music/{model => library}/RawMusicTest.kt (99%) diff --git a/app/src/main/java/org/oxycblt/auxio/detail/DetailViewModel.kt b/app/src/main/java/org/oxycblt/auxio/detail/DetailViewModel.kt index 20923abac..af6b1ca4d 100644 --- a/app/src/main/java/org/oxycblt/auxio/detail/DetailViewModel.kt +++ b/app/src/main/java/org/oxycblt/auxio/detail/DetailViewModel.kt @@ -36,10 +36,10 @@ import org.oxycblt.auxio.list.Item import org.oxycblt.auxio.list.Sort import org.oxycblt.auxio.list.adapter.UpdateInstructions import org.oxycblt.auxio.music.* +import org.oxycblt.auxio.music.library.Library import org.oxycblt.auxio.music.metadata.AudioInfo import org.oxycblt.auxio.music.metadata.Disc import org.oxycblt.auxio.music.metadata.ReleaseType -import org.oxycblt.auxio.music.model.Library import org.oxycblt.auxio.playback.PlaybackSettings import org.oxycblt.auxio.util.* diff --git a/app/src/main/java/org/oxycblt/auxio/detail/GenreDetailFragment.kt b/app/src/main/java/org/oxycblt/auxio/detail/GenreDetailFragment.kt index 555d8549a..78a2ff97d 100644 --- a/app/src/main/java/org/oxycblt/auxio/detail/GenreDetailFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/detail/GenreDetailFragment.kt @@ -38,12 +38,7 @@ import org.oxycblt.auxio.list.Item import org.oxycblt.auxio.list.ListFragment import org.oxycblt.auxio.list.Sort import org.oxycblt.auxio.list.selection.SelectionViewModel -import org.oxycblt.auxio.music.Album -import org.oxycblt.auxio.music.Artist -import org.oxycblt.auxio.music.Genre -import org.oxycblt.auxio.music.Music -import org.oxycblt.auxio.music.MusicParent -import org.oxycblt.auxio.music.Song +import org.oxycblt.auxio.music.* import org.oxycblt.auxio.playback.PlaybackViewModel import org.oxycblt.auxio.ui.NavigationViewModel import org.oxycblt.auxio.util.* @@ -233,6 +228,7 @@ class GenreDetailFragment : is Genre -> { navModel.exploreNavigationItem.consume() } + is Playlist -> TODO("handle this") null -> {} } } diff --git a/app/src/main/java/org/oxycblt/auxio/home/HomeFragment.kt b/app/src/main/java/org/oxycblt/auxio/home/HomeFragment.kt index 65b9e6f35..f20b31a8f 100644 --- a/app/src/main/java/org/oxycblt/auxio/home/HomeFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/home/HomeFragment.kt @@ -55,7 +55,7 @@ import org.oxycblt.auxio.list.Sort import org.oxycblt.auxio.list.selection.SelectionFragment import org.oxycblt.auxio.list.selection.SelectionViewModel import org.oxycblt.auxio.music.* -import org.oxycblt.auxio.music.model.Library +import org.oxycblt.auxio.music.library.Library import org.oxycblt.auxio.music.system.Indexer import org.oxycblt.auxio.playback.PlaybackViewModel import org.oxycblt.auxio.ui.MainNavigationAction diff --git a/app/src/main/java/org/oxycblt/auxio/home/HomeViewModel.kt b/app/src/main/java/org/oxycblt/auxio/home/HomeViewModel.kt index aa3058f31..c7c3f6e1d 100644 --- a/app/src/main/java/org/oxycblt/auxio/home/HomeViewModel.kt +++ b/app/src/main/java/org/oxycblt/auxio/home/HomeViewModel.kt @@ -27,7 +27,7 @@ import org.oxycblt.auxio.home.tabs.Tab import org.oxycblt.auxio.list.Sort import org.oxycblt.auxio.list.adapter.UpdateInstructions import org.oxycblt.auxio.music.* -import org.oxycblt.auxio.music.model.Library +import org.oxycblt.auxio.music.library.Library import org.oxycblt.auxio.playback.PlaybackSettings import org.oxycblt.auxio.util.Event import org.oxycblt.auxio.util.MutableEvent diff --git a/app/src/main/java/org/oxycblt/auxio/list/selection/SelectionViewModel.kt b/app/src/main/java/org/oxycblt/auxio/list/selection/SelectionViewModel.kt index 150e8552f..7971712ea 100644 --- a/app/src/main/java/org/oxycblt/auxio/list/selection/SelectionViewModel.kt +++ b/app/src/main/java/org/oxycblt/auxio/list/selection/SelectionViewModel.kt @@ -24,7 +24,7 @@ import javax.inject.Inject import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import org.oxycblt.auxio.music.* -import org.oxycblt.auxio.music.model.Library +import org.oxycblt.auxio.music.library.Library /** * A [ViewModel] that manages the current selection. @@ -57,6 +57,7 @@ class SelectionViewModel @Inject constructor(private val musicRepository: MusicR is Album -> library.sanitize(it) is Artist -> library.sanitize(it) is Genre -> library.sanitize(it) + is Playlist -> TODO("handle this") } } } diff --git a/app/src/main/java/org/oxycblt/auxio/music/Music.kt b/app/src/main/java/org/oxycblt/auxio/music/Music.kt index 0495e556e..e4b825201 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/Music.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/Music.kt @@ -21,6 +21,7 @@ package org.oxycblt.auxio.music import android.content.Context import android.net.Uri import android.os.Parcelable +import androidx.room.TypeConverter import java.security.MessageDigest import java.text.CollationKey import java.text.Collator @@ -136,6 +137,14 @@ sealed interface Music : Item { MUSICBRAINZ("org.musicbrainz") } + object TypeConverters { + /** @see [Music.UID.toString] */ + @TypeConverter fun fromMusicUID(uid: Music.UID?) = uid?.toString() + + /** @see [Music.UID.fromString] */ + @TypeConverter fun toMusicUid(string: String?) = string?.let(Music.UID::fromString) + } + companion object { /** * Creates an Auxio-style [UID] with a [UUID] composed of a hash of the non-subjective, @@ -356,6 +365,13 @@ interface Genre : MusicParent { val durationMs: Long } +/** + * A playlist. + * + * @author Alexander Capehart (OxygenCobalt) + */ +interface Playlist : MusicParent + /** * A black-box datatype for a variation of music names that is suitable for music-oriented sorting. * It will automatically handle articles like "The" and numeric components like "An". diff --git a/app/src/main/java/org/oxycblt/auxio/music/MusicRepository.kt b/app/src/main/java/org/oxycblt/auxio/music/MusicRepository.kt index 461cb6401..08e7e6452 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/MusicRepository.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/MusicRepository.kt @@ -19,7 +19,7 @@ package org.oxycblt.auxio.music import javax.inject.Inject -import org.oxycblt.auxio.music.model.Library +import org.oxycblt.auxio.music.library.Library /** * A repository granting access to the music library. diff --git a/app/src/main/java/org/oxycblt/auxio/music/cache/CacheDatabase.kt b/app/src/main/java/org/oxycblt/auxio/music/cache/CacheDatabase.kt index 8e9830aba..325736e85 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/cache/CacheDatabase.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/cache/CacheDatabase.kt @@ -27,10 +27,10 @@ import androidx.room.Query import androidx.room.RoomDatabase import androidx.room.TypeConverter import androidx.room.TypeConverters +import org.oxycblt.auxio.music.library.RawSong import org.oxycblt.auxio.music.metadata.Date import org.oxycblt.auxio.music.metadata.correctWhitespace import org.oxycblt.auxio.music.metadata.splitEscaped -import org.oxycblt.auxio.music.model.RawSong @Database(entities = [CachedSong::class], version = 27, exportSchema = false) abstract class CacheDatabase : RoomDatabase() { diff --git a/app/src/main/java/org/oxycblt/auxio/music/cache/CacheRepository.kt b/app/src/main/java/org/oxycblt/auxio/music/cache/CacheRepository.kt index 55a58ba74..8cfa1f28d 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/cache/CacheRepository.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/cache/CacheRepository.kt @@ -19,7 +19,7 @@ package org.oxycblt.auxio.music.cache import javax.inject.Inject -import org.oxycblt.auxio.music.model.RawSong +import org.oxycblt.auxio.music.library.RawSong import org.oxycblt.auxio.util.* /** diff --git a/app/src/main/java/org/oxycblt/auxio/music/model/Library.kt b/app/src/main/java/org/oxycblt/auxio/music/library/Library.kt similarity index 99% rename from app/src/main/java/org/oxycblt/auxio/music/model/Library.kt rename to app/src/main/java/org/oxycblt/auxio/music/library/Library.kt index 4f3b217c8..36a5ef7be 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/model/Library.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/library/Library.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package org.oxycblt.auxio.music.model +package org.oxycblt.auxio.music.library import android.content.Context import android.net.Uri diff --git a/app/src/main/java/org/oxycblt/auxio/music/model/MusicImpl.kt b/app/src/main/java/org/oxycblt/auxio/music/library/MusicImpl.kt similarity index 99% rename from app/src/main/java/org/oxycblt/auxio/music/model/MusicImpl.kt rename to app/src/main/java/org/oxycblt/auxio/music/library/MusicImpl.kt index 682c011fe..975fc7933 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/model/MusicImpl.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/library/MusicImpl.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package org.oxycblt.auxio.music.model +package org.oxycblt.auxio.music.library import android.content.Context import androidx.annotation.VisibleForTesting diff --git a/app/src/main/java/org/oxycblt/auxio/music/model/RawMusic.kt b/app/src/main/java/org/oxycblt/auxio/music/library/RawMusic.kt similarity index 99% rename from app/src/main/java/org/oxycblt/auxio/music/model/RawMusic.kt rename to app/src/main/java/org/oxycblt/auxio/music/library/RawMusic.kt index fa2042a60..e8acbad7e 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/model/RawMusic.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/library/RawMusic.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package org.oxycblt.auxio.music.model +package org.oxycblt.auxio.music.library import java.util.UUID import org.oxycblt.auxio.music.* diff --git a/app/src/main/java/org/oxycblt/auxio/music/metadata/TagExtractor.kt b/app/src/main/java/org/oxycblt/auxio/music/metadata/TagExtractor.kt index e9ed62dee..d6e66c094 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/metadata/TagExtractor.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/metadata/TagExtractor.kt @@ -22,7 +22,7 @@ import com.google.android.exoplayer2.MetadataRetriever import javax.inject.Inject import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.yield -import org.oxycblt.auxio.music.model.RawSong +import org.oxycblt.auxio.music.library.RawSong /** * The extractor that leverages ExoPlayer's [MetadataRetriever] API to parse metadata. This is the diff --git a/app/src/main/java/org/oxycblt/auxio/music/metadata/TagWorker.kt b/app/src/main/java/org/oxycblt/auxio/music/metadata/TagWorker.kt index 2cf328a92..62f717d9f 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/metadata/TagWorker.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/metadata/TagWorker.kt @@ -25,7 +25,7 @@ import com.google.android.exoplayer2.source.MediaSource import com.google.android.exoplayer2.source.TrackGroupArray import java.util.concurrent.Future import javax.inject.Inject -import org.oxycblt.auxio.music.model.RawSong +import org.oxycblt.auxio.music.library.RawSong import org.oxycblt.auxio.music.storage.toAudioUri import org.oxycblt.auxio.util.logD import org.oxycblt.auxio.util.logW diff --git a/app/src/main/java/org/oxycblt/auxio/playlist/Playlist.kt b/app/src/main/java/org/oxycblt/auxio/music/playlist/PlaylistDatabase.kt similarity index 55% rename from app/src/main/java/org/oxycblt/auxio/playlist/Playlist.kt rename to app/src/main/java/org/oxycblt/auxio/music/playlist/PlaylistDatabase.kt index 62697fc8e..652f0be74 100644 --- a/app/src/main/java/org/oxycblt/auxio/playlist/Playlist.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/playlist/PlaylistDatabase.kt @@ -1,6 +1,6 @@ /* * Copyright (c) 2023 Auxio Project - * Playlist.kt is part of Auxio. + * PlaylistDatabase.kt is part of Auxio. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,13 +16,21 @@ * along with this program. If not, see . */ -package org.oxycblt.auxio.playlist +package org.oxycblt.auxio.music.playlist -import java.util.UUID -import org.oxycblt.auxio.music.Song +import androidx.room.* +import org.oxycblt.auxio.music.Music -interface Playlist { - val id: UUID - val name: String - val songs: List +@Database( + entities = [PlaylistInfo::class, PlaylistSong::class, PlaylistSongCrossRef::class], + version = 28, + exportSchema = false) +@TypeConverters(Music.UID.TypeConverters::class) +abstract class PlaylistDatabase : RoomDatabase() { + abstract fun playlistDao(): PlaylistDao +} + +@Dao +interface PlaylistDao { + @Transaction @Query("SELECT * FROM PlaylistInfo") fun readRawPlaylists(): List } diff --git a/app/src/main/java/org/oxycblt/auxio/music/playlist/PlaylistImpl.kt b/app/src/main/java/org/oxycblt/auxio/music/playlist/PlaylistImpl.kt new file mode 100644 index 000000000..dcb80a237 --- /dev/null +++ b/app/src/main/java/org/oxycblt/auxio/music/playlist/PlaylistImpl.kt @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2023 Auxio Project + * PlaylistImpl.kt is part of Auxio. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.oxycblt.auxio.music.playlist + +import android.content.Context +import org.oxycblt.auxio.music.* +import org.oxycblt.auxio.music.library.Library + +class PlaylistImpl(rawPlaylist: RawPlaylist, library: Library, musicSettings: MusicSettings) : + Playlist { + override val uid = rawPlaylist.playlistInfo.playlistUid + override val rawName = rawPlaylist.playlistInfo.name + override fun resolveName(context: Context) = rawName + override val rawSortName = null + override val sortName = SortName(rawName, musicSettings) + override val songs = rawPlaylist.songs.mapNotNull { library.find(it.songUid) } +} diff --git a/app/src/main/java/org/oxycblt/auxio/playlist/PlaylistModule.kt b/app/src/main/java/org/oxycblt/auxio/music/playlist/PlaylistModule.kt similarity index 57% rename from app/src/main/java/org/oxycblt/auxio/playlist/PlaylistModule.kt rename to app/src/main/java/org/oxycblt/auxio/music/playlist/PlaylistModule.kt index fba4dc489..45da01dc7 100644 --- a/app/src/main/java/org/oxycblt/auxio/playlist/PlaylistModule.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/playlist/PlaylistModule.kt @@ -16,16 +16,27 @@ * along with this program. If not, see . */ -package org.oxycblt.auxio.playlist +package org.oxycblt.auxio.music.playlist -import dagger.Binds +import android.content.Context +import androidx.room.Room import dagger.Module +import dagger.Provides import dagger.hilt.InstallIn +import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.components.SingletonComponent @Module @InstallIn(SingletonComponent::class) -interface PlaylistModule { - @Binds - fun playlistRepository(playlistRepositoryImpl: PlaylistRepositoryImpl): PlaylistRepository +class PlaylistModule { + @Provides fun playlistDao(database: PlaylistDatabase) = database.playlistDao() + + @Provides + fun playlistDatabase(@ApplicationContext context: Context) = + Room.databaseBuilder( + context.applicationContext, PlaylistDatabase::class.java, "playlists.db") + .fallbackToDestructiveMigration() + .fallbackToDestructiveMigrationFrom(0) + .fallbackToDestructiveMigrationOnDowngrade() + .build() } diff --git a/app/src/main/java/org/oxycblt/auxio/music/playlist/RawPlaylist.kt b/app/src/main/java/org/oxycblt/auxio/music/playlist/RawPlaylist.kt new file mode 100644 index 000000000..58f232f47 --- /dev/null +++ b/app/src/main/java/org/oxycblt/auxio/music/playlist/RawPlaylist.kt @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2023 Auxio Project + * RawPlaylist.kt is part of Auxio. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.oxycblt.auxio.music.playlist + +import androidx.room.* +import org.oxycblt.auxio.music.Music + +data class RawPlaylist( + @Embedded val playlistInfo: PlaylistInfo, + @Relation( + parentColumn = "playlistUid", + entityColumn = "songUid", + associateBy = Junction(PlaylistSongCrossRef::class)) + val songs: List +) + +@Entity data class PlaylistInfo(@PrimaryKey val playlistUid: Music.UID, val name: String) + +@Entity data class PlaylistSong(@PrimaryKey val songUid: Music.UID) + +@Entity(primaryKeys = ["playlistUid", "songUid"]) +data class PlaylistSongCrossRef( + val playlistUid: Music.UID, + @ColumnInfo(index = true) val songUid: Music.UID +) diff --git a/app/src/main/java/org/oxycblt/auxio/music/storage/MediaStoreExtractor.kt b/app/src/main/java/org/oxycblt/auxio/music/storage/MediaStoreExtractor.kt index 1669ae516..5ea3a6cbf 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/storage/MediaStoreExtractor.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/storage/MediaStoreExtractor.kt @@ -31,10 +31,10 @@ import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.yield import org.oxycblt.auxio.music.MusicSettings import org.oxycblt.auxio.music.cache.Cache +import org.oxycblt.auxio.music.library.RawSong import org.oxycblt.auxio.music.metadata.Date import org.oxycblt.auxio.music.metadata.parseId3v2PositionField import org.oxycblt.auxio.music.metadata.transformPositionField -import org.oxycblt.auxio.music.model.RawSong import org.oxycblt.auxio.util.getSystemServiceCompat import org.oxycblt.auxio.util.logD diff --git a/app/src/main/java/org/oxycblt/auxio/music/system/Indexer.kt b/app/src/main/java/org/oxycblt/auxio/music/system/Indexer.kt index a5daf2118..1fd305c63 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/system/Indexer.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/system/Indexer.kt @@ -37,9 +37,9 @@ import kotlinx.coroutines.yield import org.oxycblt.auxio.BuildConfig import org.oxycblt.auxio.music.* import org.oxycblt.auxio.music.cache.CacheRepository +import org.oxycblt.auxio.music.library.Library +import org.oxycblt.auxio.music.library.RawSong import org.oxycblt.auxio.music.metadata.TagExtractor -import org.oxycblt.auxio.music.model.Library -import org.oxycblt.auxio.music.model.RawSong import org.oxycblt.auxio.music.storage.MediaStoreExtractor import org.oxycblt.auxio.util.logD import org.oxycblt.auxio.util.logE diff --git a/app/src/main/java/org/oxycblt/auxio/picker/PickerViewModel.kt b/app/src/main/java/org/oxycblt/auxio/picker/PickerViewModel.kt index c10892dd5..e670078f5 100644 --- a/app/src/main/java/org/oxycblt/auxio/picker/PickerViewModel.kt +++ b/app/src/main/java/org/oxycblt/auxio/picker/PickerViewModel.kt @@ -24,7 +24,7 @@ import javax.inject.Inject import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import org.oxycblt.auxio.music.* -import org.oxycblt.auxio.music.model.Library +import org.oxycblt.auxio.music.library.Library import org.oxycblt.auxio.util.unlikelyToBeNull /** diff --git a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackViewModel.kt b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackViewModel.kt index 9301bb341..0bf724abf 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackViewModel.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackViewModel.kt @@ -287,6 +287,7 @@ constructor( is Genre -> musicSettings.genreSongSort is Artist -> musicSettings.artistSongSort is Album -> musicSettings.albumSongSort + is Playlist -> TODO("handle this") null -> musicSettings.songSort } val queue = sort.songs(parent?.songs ?: library.songs) @@ -494,6 +495,7 @@ constructor( is Artist -> musicSettings.artistSongSort.songs(it.songs) is Genre -> musicSettings.genreSongSort.songs(it.songs) is Song -> listOf(it) + is Playlist -> TODO("handle this") } } } diff --git a/app/src/main/java/org/oxycblt/auxio/playback/persist/PersistenceDatabase.kt b/app/src/main/java/org/oxycblt/auxio/playback/persist/PersistenceDatabase.kt index a61731213..8c6e59a6d 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/persist/PersistenceDatabase.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/persist/PersistenceDatabase.kt @@ -26,7 +26,6 @@ import androidx.room.OnConflictStrategy import androidx.room.PrimaryKey import androidx.room.Query import androidx.room.RoomDatabase -import androidx.room.TypeConverter import androidx.room.TypeConverters import org.oxycblt.auxio.music.Music import org.oxycblt.auxio.playback.state.RepeatMode @@ -40,7 +39,7 @@ import org.oxycblt.auxio.playback.state.RepeatMode entities = [PlaybackState::class, QueueHeapItem::class, QueueMappingItem::class], version = 27, exportSchema = false) -@TypeConverters(PersistenceDatabase.Converters::class) +@TypeConverters(Music.UID.TypeConverters::class) abstract class PersistenceDatabase : RoomDatabase() { /** * Get the current [PlaybackStateDao]. @@ -55,14 +54,6 @@ abstract class PersistenceDatabase : RoomDatabase() { * @return A [QueueDao] providing control of the database's queue tables. */ abstract fun queueDao(): QueueDao - - object Converters { - /** @see [Music.UID.toString] */ - @TypeConverter fun fromMusicUID(uid: Music.UID?) = uid?.toString() - - /** @see [Music.UID.fromString] */ - @TypeConverter fun toMusicUid(string: String?) = string?.let(Music.UID::fromString) - } } /** diff --git a/app/src/main/java/org/oxycblt/auxio/playback/persist/PersistenceRepository.kt b/app/src/main/java/org/oxycblt/auxio/playback/persist/PersistenceRepository.kt index 9ce5d89d2..38cbba829 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/persist/PersistenceRepository.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/persist/PersistenceRepository.kt @@ -20,7 +20,7 @@ package org.oxycblt.auxio.playback.persist import javax.inject.Inject import org.oxycblt.auxio.music.MusicParent -import org.oxycblt.auxio.music.model.Library +import org.oxycblt.auxio.music.library.Library import org.oxycblt.auxio.playback.queue.Queue import org.oxycblt.auxio.playback.state.PlaybackStateManager import org.oxycblt.auxio.util.logD diff --git a/app/src/main/java/org/oxycblt/auxio/playback/system/PlaybackService.kt b/app/src/main/java/org/oxycblt/auxio/playback/system/PlaybackService.kt index 4dd18fb85..8f4480845 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/system/PlaybackService.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/system/PlaybackService.kt @@ -48,7 +48,7 @@ import org.oxycblt.auxio.BuildConfig import org.oxycblt.auxio.music.MusicRepository import org.oxycblt.auxio.music.MusicSettings import org.oxycblt.auxio.music.Song -import org.oxycblt.auxio.music.model.Library +import org.oxycblt.auxio.music.library.Library import org.oxycblt.auxio.playback.PlaybackSettings import org.oxycblt.auxio.playback.persist.PersistenceRepository import org.oxycblt.auxio.playback.replaygain.ReplayGainAudioProcessor diff --git a/app/src/main/java/org/oxycblt/auxio/playlist/PlaylistRepository.kt b/app/src/main/java/org/oxycblt/auxio/playlist/PlaylistRepository.kt deleted file mode 100644 index 90fcb5f0c..000000000 --- a/app/src/main/java/org/oxycblt/auxio/playlist/PlaylistRepository.kt +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2023 Auxio Project - * PlaylistRepository.kt is part of Auxio. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.oxycblt.auxio.playlist - -import java.util.UUID -import javax.inject.Inject -import org.oxycblt.auxio.music.Song - -interface PlaylistRepository { - val playlists: List - suspend fun createPlaylist(name: String, songs: List) - suspend fun deletePlaylist(playlist: Playlist) - suspend fun addToPlaylist(playlist: Playlist, songs: List) - suspend fun removeFromPlaylist(playlist: Playlist, song: Song) - suspend fun rewritePlaylist(playlist: Playlist, songs: List) -} - -class PlaylistRepositoryImpl @Inject constructor() : PlaylistRepository { - private val playlistMap = mutableMapOf() - override val playlists: List - get() = playlistMap.values.toList() - - override suspend fun createPlaylist(name: String, songs: List) { - val uuid = UUID.randomUUID() - playlistMap[uuid] = PlaylistImpl(uuid, name, songs) - } - - override suspend fun deletePlaylist(playlist: Playlist) { - playlistMap.remove(playlist.id) - } - - override suspend fun addToPlaylist(playlist: Playlist, songs: List) { - editPlaylist(playlist) { - addAll(songs) - this - } - } - - override suspend fun removeFromPlaylist(playlist: Playlist, song: Song) { - editPlaylist(playlist) { - remove(song) - this - } - } - - override suspend fun rewritePlaylist(playlist: Playlist, songs: List) { - editPlaylist(playlist) { songs } - } - - private inline fun editPlaylist(playlist: Playlist, edits: MutableList.() -> List) { - check(playlistMap.containsKey(playlist.id)) { "Invalid playlist argument provided" } - playlistMap[playlist.id] = - PlaylistImpl(playlist.id, playlist.name, edits(playlist.songs.toMutableList())) - } -} - -private data class PlaylistImpl( - override val id: UUID, - override val name: String, - override val songs: List -) : Playlist diff --git a/app/src/main/java/org/oxycblt/auxio/search/SearchFragment.kt b/app/src/main/java/org/oxycblt/auxio/search/SearchFragment.kt index 35ff34079..ce118eee4 100644 --- a/app/src/main/java/org/oxycblt/auxio/search/SearchFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/search/SearchFragment.kt @@ -36,12 +36,7 @@ import org.oxycblt.auxio.databinding.FragmentSearchBinding import org.oxycblt.auxio.list.Item import org.oxycblt.auxio.list.ListFragment import org.oxycblt.auxio.list.selection.SelectionViewModel -import org.oxycblt.auxio.music.Album -import org.oxycblt.auxio.music.Artist -import org.oxycblt.auxio.music.Genre -import org.oxycblt.auxio.music.Music -import org.oxycblt.auxio.music.MusicParent -import org.oxycblt.auxio.music.Song +import org.oxycblt.auxio.music.* import org.oxycblt.auxio.playback.PlaybackViewModel import org.oxycblt.auxio.ui.NavigationViewModel import org.oxycblt.auxio.util.* @@ -155,6 +150,7 @@ class SearchFragment : ListFragment() { is Album -> openMusicMenu(anchor, R.menu.menu_album_actions, item) is Artist -> openMusicMenu(anchor, R.menu.menu_artist_actions, item) is Genre -> openMusicMenu(anchor, R.menu.menu_artist_actions, item) + is Playlist -> TODO("handle this") } } diff --git a/app/src/main/java/org/oxycblt/auxio/search/SearchViewModel.kt b/app/src/main/java/org/oxycblt/auxio/search/SearchViewModel.kt index 4af58703c..a36b475c3 100644 --- a/app/src/main/java/org/oxycblt/auxio/search/SearchViewModel.kt +++ b/app/src/main/java/org/oxycblt/auxio/search/SearchViewModel.kt @@ -33,7 +33,7 @@ import org.oxycblt.auxio.list.BasicHeader import org.oxycblt.auxio.list.Item import org.oxycblt.auxio.list.Sort import org.oxycblt.auxio.music.* -import org.oxycblt.auxio.music.model.Library +import org.oxycblt.auxio.music.library.Library import org.oxycblt.auxio.playback.PlaybackSettings import org.oxycblt.auxio.util.logD diff --git a/app/src/test/java/org/oxycblt/auxio/music/MusicRepositoryTest.kt b/app/src/test/java/org/oxycblt/auxio/music/MusicRepositoryTest.kt index 832bfee70..fe18dc326 100644 --- a/app/src/test/java/org/oxycblt/auxio/music/MusicRepositoryTest.kt +++ b/app/src/test/java/org/oxycblt/auxio/music/MusicRepositoryTest.kt @@ -20,8 +20,8 @@ package org.oxycblt.auxio.music import org.junit.Assert.assertEquals import org.junit.Test -import org.oxycblt.auxio.music.model.FakeLibrary -import org.oxycblt.auxio.music.model.Library +import org.oxycblt.auxio.music.library.FakeLibrary +import org.oxycblt.auxio.music.library.Library class MusicRepositoryTest { @Test diff --git a/app/src/test/java/org/oxycblt/auxio/music/MusicViewModelTest.kt b/app/src/test/java/org/oxycblt/auxio/music/MusicViewModelTest.kt index d9ff955bf..078624d69 100644 --- a/app/src/test/java/org/oxycblt/auxio/music/MusicViewModelTest.kt +++ b/app/src/test/java/org/oxycblt/auxio/music/MusicViewModelTest.kt @@ -21,7 +21,7 @@ package org.oxycblt.auxio.music import org.junit.Assert.assertEquals import org.junit.Assert.assertTrue import org.junit.Test -import org.oxycblt.auxio.music.model.FakeLibrary +import org.oxycblt.auxio.music.library.FakeLibrary import org.oxycblt.auxio.music.system.FakeIndexer import org.oxycblt.auxio.music.system.Indexer import org.oxycblt.auxio.util.forceClear diff --git a/app/src/test/java/org/oxycblt/auxio/music/model/FakeLibrary.kt b/app/src/test/java/org/oxycblt/auxio/music/library/FakeLibrary.kt similarity index 97% rename from app/src/test/java/org/oxycblt/auxio/music/model/FakeLibrary.kt rename to app/src/test/java/org/oxycblt/auxio/music/library/FakeLibrary.kt index 3144b4db0..7230e5e76 100644 --- a/app/src/test/java/org/oxycblt/auxio/music/model/FakeLibrary.kt +++ b/app/src/test/java/org/oxycblt/auxio/music/library/FakeLibrary.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package org.oxycblt.auxio.music.model +package org.oxycblt.auxio.music.library import android.content.Context import android.net.Uri diff --git a/app/src/test/java/org/oxycblt/auxio/music/model/RawMusicTest.kt b/app/src/test/java/org/oxycblt/auxio/music/library/RawMusicTest.kt similarity index 99% rename from app/src/test/java/org/oxycblt/auxio/music/model/RawMusicTest.kt rename to app/src/test/java/org/oxycblt/auxio/music/library/RawMusicTest.kt index 9033aebd7..a4fafb324 100644 --- a/app/src/test/java/org/oxycblt/auxio/music/model/RawMusicTest.kt +++ b/app/src/test/java/org/oxycblt/auxio/music/library/RawMusicTest.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package org.oxycblt.auxio.music.model +package org.oxycblt.auxio.music.library import java.util.* import org.junit.Assert.assertEquals