playlist: consider playlists music
Consider playlists music rather than an extension of music. This also sets up the basics of a playlist datbaase.
This commit is contained in:
parent
5e3b4a2fce
commit
4033a791a7
32 changed files with 154 additions and 136 deletions
|
@ -36,10 +36,10 @@ import org.oxycblt.auxio.list.Item
|
||||||
import org.oxycblt.auxio.list.Sort
|
import org.oxycblt.auxio.list.Sort
|
||||||
import org.oxycblt.auxio.list.adapter.UpdateInstructions
|
import org.oxycblt.auxio.list.adapter.UpdateInstructions
|
||||||
import org.oxycblt.auxio.music.*
|
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.AudioInfo
|
||||||
import org.oxycblt.auxio.music.metadata.Disc
|
import org.oxycblt.auxio.music.metadata.Disc
|
||||||
import org.oxycblt.auxio.music.metadata.ReleaseType
|
import org.oxycblt.auxio.music.metadata.ReleaseType
|
||||||
import org.oxycblt.auxio.music.model.Library
|
|
||||||
import org.oxycblt.auxio.playback.PlaybackSettings
|
import org.oxycblt.auxio.playback.PlaybackSettings
|
||||||
import org.oxycblt.auxio.util.*
|
import org.oxycblt.auxio.util.*
|
||||||
|
|
||||||
|
|
|
@ -38,12 +38,7 @@ import org.oxycblt.auxio.list.Item
|
||||||
import org.oxycblt.auxio.list.ListFragment
|
import org.oxycblt.auxio.list.ListFragment
|
||||||
import org.oxycblt.auxio.list.Sort
|
import org.oxycblt.auxio.list.Sort
|
||||||
import org.oxycblt.auxio.list.selection.SelectionViewModel
|
import org.oxycblt.auxio.list.selection.SelectionViewModel
|
||||||
import org.oxycblt.auxio.music.Album
|
import org.oxycblt.auxio.music.*
|
||||||
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.playback.PlaybackViewModel
|
import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||||
import org.oxycblt.auxio.ui.NavigationViewModel
|
import org.oxycblt.auxio.ui.NavigationViewModel
|
||||||
import org.oxycblt.auxio.util.*
|
import org.oxycblt.auxio.util.*
|
||||||
|
@ -233,6 +228,7 @@ class GenreDetailFragment :
|
||||||
is Genre -> {
|
is Genre -> {
|
||||||
navModel.exploreNavigationItem.consume()
|
navModel.exploreNavigationItem.consume()
|
||||||
}
|
}
|
||||||
|
is Playlist -> TODO("handle this")
|
||||||
null -> {}
|
null -> {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,7 @@ import org.oxycblt.auxio.list.Sort
|
||||||
import org.oxycblt.auxio.list.selection.SelectionFragment
|
import org.oxycblt.auxio.list.selection.SelectionFragment
|
||||||
import org.oxycblt.auxio.list.selection.SelectionViewModel
|
import org.oxycblt.auxio.list.selection.SelectionViewModel
|
||||||
import org.oxycblt.auxio.music.*
|
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.music.system.Indexer
|
||||||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||||
import org.oxycblt.auxio.ui.MainNavigationAction
|
import org.oxycblt.auxio.ui.MainNavigationAction
|
||||||
|
|
|
@ -27,7 +27,7 @@ import org.oxycblt.auxio.home.tabs.Tab
|
||||||
import org.oxycblt.auxio.list.Sort
|
import org.oxycblt.auxio.list.Sort
|
||||||
import org.oxycblt.auxio.list.adapter.UpdateInstructions
|
import org.oxycblt.auxio.list.adapter.UpdateInstructions
|
||||||
import org.oxycblt.auxio.music.*
|
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.playback.PlaybackSettings
|
||||||
import org.oxycblt.auxio.util.Event
|
import org.oxycblt.auxio.util.Event
|
||||||
import org.oxycblt.auxio.util.MutableEvent
|
import org.oxycblt.auxio.util.MutableEvent
|
||||||
|
|
|
@ -24,7 +24,7 @@ import javax.inject.Inject
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import org.oxycblt.auxio.music.*
|
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.
|
* 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 Album -> library.sanitize(it)
|
||||||
is Artist -> library.sanitize(it)
|
is Artist -> library.sanitize(it)
|
||||||
is Genre -> library.sanitize(it)
|
is Genre -> library.sanitize(it)
|
||||||
|
is Playlist -> TODO("handle this")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ package org.oxycblt.auxio.music
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
|
import androidx.room.TypeConverter
|
||||||
import java.security.MessageDigest
|
import java.security.MessageDigest
|
||||||
import java.text.CollationKey
|
import java.text.CollationKey
|
||||||
import java.text.Collator
|
import java.text.Collator
|
||||||
|
@ -136,6 +137,14 @@ sealed interface Music : Item {
|
||||||
MUSICBRAINZ("org.musicbrainz")
|
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 {
|
companion object {
|
||||||
/**
|
/**
|
||||||
* Creates an Auxio-style [UID] with a [UUID] composed of a hash of the non-subjective,
|
* 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
|
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.
|
* 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".
|
* It will automatically handle articles like "The" and numeric components like "An".
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
package org.oxycblt.auxio.music
|
package org.oxycblt.auxio.music
|
||||||
|
|
||||||
import javax.inject.Inject
|
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.
|
* A repository granting access to the music library.
|
||||||
|
|
|
@ -27,10 +27,10 @@ import androidx.room.Query
|
||||||
import androidx.room.RoomDatabase
|
import androidx.room.RoomDatabase
|
||||||
import androidx.room.TypeConverter
|
import androidx.room.TypeConverter
|
||||||
import androidx.room.TypeConverters
|
import androidx.room.TypeConverters
|
||||||
|
import org.oxycblt.auxio.music.library.RawSong
|
||||||
import org.oxycblt.auxio.music.metadata.Date
|
import org.oxycblt.auxio.music.metadata.Date
|
||||||
import org.oxycblt.auxio.music.metadata.correctWhitespace
|
import org.oxycblt.auxio.music.metadata.correctWhitespace
|
||||||
import org.oxycblt.auxio.music.metadata.splitEscaped
|
import org.oxycblt.auxio.music.metadata.splitEscaped
|
||||||
import org.oxycblt.auxio.music.model.RawSong
|
|
||||||
|
|
||||||
@Database(entities = [CachedSong::class], version = 27, exportSchema = false)
|
@Database(entities = [CachedSong::class], version = 27, exportSchema = false)
|
||||||
abstract class CacheDatabase : RoomDatabase() {
|
abstract class CacheDatabase : RoomDatabase() {
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
package org.oxycblt.auxio.music.cache
|
package org.oxycblt.auxio.music.cache
|
||||||
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import org.oxycblt.auxio.music.model.RawSong
|
import org.oxycblt.auxio.music.library.RawSong
|
||||||
import org.oxycblt.auxio.util.*
|
import org.oxycblt.auxio.util.*
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.oxycblt.auxio.music.model
|
package org.oxycblt.auxio.music.library
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.net.Uri
|
import android.net.Uri
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.oxycblt.auxio.music.model
|
package org.oxycblt.auxio.music.library
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.annotation.VisibleForTesting
|
import androidx.annotation.VisibleForTesting
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.oxycblt.auxio.music.model
|
package org.oxycblt.auxio.music.library
|
||||||
|
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
import org.oxycblt.auxio.music.*
|
import org.oxycblt.auxio.music.*
|
|
@ -22,7 +22,7 @@ import com.google.android.exoplayer2.MetadataRetriever
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import kotlinx.coroutines.channels.Channel
|
import kotlinx.coroutines.channels.Channel
|
||||||
import kotlinx.coroutines.yield
|
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
|
* The extractor that leverages ExoPlayer's [MetadataRetriever] API to parse metadata. This is the
|
||||||
|
|
|
@ -25,7 +25,7 @@ import com.google.android.exoplayer2.source.MediaSource
|
||||||
import com.google.android.exoplayer2.source.TrackGroupArray
|
import com.google.android.exoplayer2.source.TrackGroupArray
|
||||||
import java.util.concurrent.Future
|
import java.util.concurrent.Future
|
||||||
import javax.inject.Inject
|
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.music.storage.toAudioUri
|
||||||
import org.oxycblt.auxio.util.logD
|
import org.oxycblt.auxio.util.logD
|
||||||
import org.oxycblt.auxio.util.logW
|
import org.oxycblt.auxio.util.logW
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2023 Auxio Project
|
* 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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -16,13 +16,21 @@
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.oxycblt.auxio.playlist
|
package org.oxycblt.auxio.music.playlist
|
||||||
|
|
||||||
import java.util.UUID
|
import androidx.room.*
|
||||||
import org.oxycblt.auxio.music.Song
|
import org.oxycblt.auxio.music.Music
|
||||||
|
|
||||||
interface Playlist {
|
@Database(
|
||||||
val id: UUID
|
entities = [PlaylistInfo::class, PlaylistSong::class, PlaylistSongCrossRef::class],
|
||||||
val name: String
|
version = 28,
|
||||||
val songs: List<Song>
|
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<RawPlaylist>
|
||||||
}
|
}
|
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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<Song>(it.songUid) }
|
||||||
|
}
|
|
@ -16,16 +16,27 @@
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
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.Module
|
||||||
|
import dagger.Provides
|
||||||
import dagger.hilt.InstallIn
|
import dagger.hilt.InstallIn
|
||||||
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
import dagger.hilt.components.SingletonComponent
|
import dagger.hilt.components.SingletonComponent
|
||||||
|
|
||||||
@Module
|
@Module
|
||||||
@InstallIn(SingletonComponent::class)
|
@InstallIn(SingletonComponent::class)
|
||||||
interface PlaylistModule {
|
class PlaylistModule {
|
||||||
@Binds
|
@Provides fun playlistDao(database: PlaylistDatabase) = database.playlistDao()
|
||||||
fun playlistRepository(playlistRepositoryImpl: PlaylistRepositoryImpl): PlaylistRepository
|
|
||||||
|
@Provides
|
||||||
|
fun playlistDatabase(@ApplicationContext context: Context) =
|
||||||
|
Room.databaseBuilder(
|
||||||
|
context.applicationContext, PlaylistDatabase::class.java, "playlists.db")
|
||||||
|
.fallbackToDestructiveMigration()
|
||||||
|
.fallbackToDestructiveMigrationFrom(0)
|
||||||
|
.fallbackToDestructiveMigrationOnDowngrade()
|
||||||
|
.build()
|
||||||
}
|
}
|
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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<PlaylistSong>
|
||||||
|
)
|
||||||
|
|
||||||
|
@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
|
||||||
|
)
|
|
@ -31,10 +31,10 @@ import kotlinx.coroutines.channels.Channel
|
||||||
import kotlinx.coroutines.yield
|
import kotlinx.coroutines.yield
|
||||||
import org.oxycblt.auxio.music.MusicSettings
|
import org.oxycblt.auxio.music.MusicSettings
|
||||||
import org.oxycblt.auxio.music.cache.Cache
|
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.Date
|
||||||
import org.oxycblt.auxio.music.metadata.parseId3v2PositionField
|
import org.oxycblt.auxio.music.metadata.parseId3v2PositionField
|
||||||
import org.oxycblt.auxio.music.metadata.transformPositionField
|
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.getSystemServiceCompat
|
||||||
import org.oxycblt.auxio.util.logD
|
import org.oxycblt.auxio.util.logD
|
||||||
|
|
||||||
|
|
|
@ -37,9 +37,9 @@ import kotlinx.coroutines.yield
|
||||||
import org.oxycblt.auxio.BuildConfig
|
import org.oxycblt.auxio.BuildConfig
|
||||||
import org.oxycblt.auxio.music.*
|
import org.oxycblt.auxio.music.*
|
||||||
import org.oxycblt.auxio.music.cache.CacheRepository
|
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.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.music.storage.MediaStoreExtractor
|
||||||
import org.oxycblt.auxio.util.logD
|
import org.oxycblt.auxio.util.logD
|
||||||
import org.oxycblt.auxio.util.logE
|
import org.oxycblt.auxio.util.logE
|
||||||
|
|
|
@ -24,7 +24,7 @@ import javax.inject.Inject
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import org.oxycblt.auxio.music.*
|
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
|
import org.oxycblt.auxio.util.unlikelyToBeNull
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -287,6 +287,7 @@ constructor(
|
||||||
is Genre -> musicSettings.genreSongSort
|
is Genre -> musicSettings.genreSongSort
|
||||||
is Artist -> musicSettings.artistSongSort
|
is Artist -> musicSettings.artistSongSort
|
||||||
is Album -> musicSettings.albumSongSort
|
is Album -> musicSettings.albumSongSort
|
||||||
|
is Playlist -> TODO("handle this")
|
||||||
null -> musicSettings.songSort
|
null -> musicSettings.songSort
|
||||||
}
|
}
|
||||||
val queue = sort.songs(parent?.songs ?: library.songs)
|
val queue = sort.songs(parent?.songs ?: library.songs)
|
||||||
|
@ -494,6 +495,7 @@ constructor(
|
||||||
is Artist -> musicSettings.artistSongSort.songs(it.songs)
|
is Artist -> musicSettings.artistSongSort.songs(it.songs)
|
||||||
is Genre -> musicSettings.genreSongSort.songs(it.songs)
|
is Genre -> musicSettings.genreSongSort.songs(it.songs)
|
||||||
is Song -> listOf(it)
|
is Song -> listOf(it)
|
||||||
|
is Playlist -> TODO("handle this")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,6 @@ import androidx.room.OnConflictStrategy
|
||||||
import androidx.room.PrimaryKey
|
import androidx.room.PrimaryKey
|
||||||
import androidx.room.Query
|
import androidx.room.Query
|
||||||
import androidx.room.RoomDatabase
|
import androidx.room.RoomDatabase
|
||||||
import androidx.room.TypeConverter
|
|
||||||
import androidx.room.TypeConverters
|
import androidx.room.TypeConverters
|
||||||
import org.oxycblt.auxio.music.Music
|
import org.oxycblt.auxio.music.Music
|
||||||
import org.oxycblt.auxio.playback.state.RepeatMode
|
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],
|
entities = [PlaybackState::class, QueueHeapItem::class, QueueMappingItem::class],
|
||||||
version = 27,
|
version = 27,
|
||||||
exportSchema = false)
|
exportSchema = false)
|
||||||
@TypeConverters(PersistenceDatabase.Converters::class)
|
@TypeConverters(Music.UID.TypeConverters::class)
|
||||||
abstract class PersistenceDatabase : RoomDatabase() {
|
abstract class PersistenceDatabase : RoomDatabase() {
|
||||||
/**
|
/**
|
||||||
* Get the current [PlaybackStateDao].
|
* Get the current [PlaybackStateDao].
|
||||||
|
@ -55,14 +54,6 @@ abstract class PersistenceDatabase : RoomDatabase() {
|
||||||
* @return A [QueueDao] providing control of the database's queue tables.
|
* @return A [QueueDao] providing control of the database's queue tables.
|
||||||
*/
|
*/
|
||||||
abstract fun queueDao(): QueueDao
|
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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -20,7 +20,7 @@ package org.oxycblt.auxio.playback.persist
|
||||||
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import org.oxycblt.auxio.music.MusicParent
|
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.queue.Queue
|
||||||
import org.oxycblt.auxio.playback.state.PlaybackStateManager
|
import org.oxycblt.auxio.playback.state.PlaybackStateManager
|
||||||
import org.oxycblt.auxio.util.logD
|
import org.oxycblt.auxio.util.logD
|
||||||
|
|
|
@ -48,7 +48,7 @@ import org.oxycblt.auxio.BuildConfig
|
||||||
import org.oxycblt.auxio.music.MusicRepository
|
import org.oxycblt.auxio.music.MusicRepository
|
||||||
import org.oxycblt.auxio.music.MusicSettings
|
import org.oxycblt.auxio.music.MusicSettings
|
||||||
import org.oxycblt.auxio.music.Song
|
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.PlaybackSettings
|
||||||
import org.oxycblt.auxio.playback.persist.PersistenceRepository
|
import org.oxycblt.auxio.playback.persist.PersistenceRepository
|
||||||
import org.oxycblt.auxio.playback.replaygain.ReplayGainAudioProcessor
|
import org.oxycblt.auxio.playback.replaygain.ReplayGainAudioProcessor
|
||||||
|
|
|
@ -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 <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.oxycblt.auxio.playlist
|
|
||||||
|
|
||||||
import java.util.UUID
|
|
||||||
import javax.inject.Inject
|
|
||||||
import org.oxycblt.auxio.music.Song
|
|
||||||
|
|
||||||
interface PlaylistRepository {
|
|
||||||
val playlists: List<Playlist>
|
|
||||||
suspend fun createPlaylist(name: String, songs: List<Song>)
|
|
||||||
suspend fun deletePlaylist(playlist: Playlist)
|
|
||||||
suspend fun addToPlaylist(playlist: Playlist, songs: List<Song>)
|
|
||||||
suspend fun removeFromPlaylist(playlist: Playlist, song: Song)
|
|
||||||
suspend fun rewritePlaylist(playlist: Playlist, songs: List<Song>)
|
|
||||||
}
|
|
||||||
|
|
||||||
class PlaylistRepositoryImpl @Inject constructor() : PlaylistRepository {
|
|
||||||
private val playlistMap = mutableMapOf<UUID, PlaylistImpl>()
|
|
||||||
override val playlists: List<Playlist>
|
|
||||||
get() = playlistMap.values.toList()
|
|
||||||
|
|
||||||
override suspend fun createPlaylist(name: String, songs: List<Song>) {
|
|
||||||
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<Song>) {
|
|
||||||
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<Song>) {
|
|
||||||
editPlaylist(playlist) { songs }
|
|
||||||
}
|
|
||||||
|
|
||||||
private inline fun editPlaylist(playlist: Playlist, edits: MutableList<Song>.() -> List<Song>) {
|
|
||||||
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<Song>
|
|
||||||
) : Playlist
|
|
|
@ -36,12 +36,7 @@ import org.oxycblt.auxio.databinding.FragmentSearchBinding
|
||||||
import org.oxycblt.auxio.list.Item
|
import org.oxycblt.auxio.list.Item
|
||||||
import org.oxycblt.auxio.list.ListFragment
|
import org.oxycblt.auxio.list.ListFragment
|
||||||
import org.oxycblt.auxio.list.selection.SelectionViewModel
|
import org.oxycblt.auxio.list.selection.SelectionViewModel
|
||||||
import org.oxycblt.auxio.music.Album
|
import org.oxycblt.auxio.music.*
|
||||||
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.playback.PlaybackViewModel
|
import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||||
import org.oxycblt.auxio.ui.NavigationViewModel
|
import org.oxycblt.auxio.ui.NavigationViewModel
|
||||||
import org.oxycblt.auxio.util.*
|
import org.oxycblt.auxio.util.*
|
||||||
|
@ -155,6 +150,7 @@ class SearchFragment : ListFragment<Music, FragmentSearchBinding>() {
|
||||||
is Album -> openMusicMenu(anchor, R.menu.menu_album_actions, item)
|
is Album -> openMusicMenu(anchor, R.menu.menu_album_actions, item)
|
||||||
is Artist -> openMusicMenu(anchor, R.menu.menu_artist_actions, item)
|
is Artist -> openMusicMenu(anchor, R.menu.menu_artist_actions, item)
|
||||||
is Genre -> openMusicMenu(anchor, R.menu.menu_artist_actions, item)
|
is Genre -> openMusicMenu(anchor, R.menu.menu_artist_actions, item)
|
||||||
|
is Playlist -> TODO("handle this")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ import org.oxycblt.auxio.list.BasicHeader
|
||||||
import org.oxycblt.auxio.list.Item
|
import org.oxycblt.auxio.list.Item
|
||||||
import org.oxycblt.auxio.list.Sort
|
import org.oxycblt.auxio.list.Sort
|
||||||
import org.oxycblt.auxio.music.*
|
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.playback.PlaybackSettings
|
||||||
import org.oxycblt.auxio.util.logD
|
import org.oxycblt.auxio.util.logD
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,8 @@ package org.oxycblt.auxio.music
|
||||||
|
|
||||||
import org.junit.Assert.assertEquals
|
import org.junit.Assert.assertEquals
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.oxycblt.auxio.music.model.FakeLibrary
|
import org.oxycblt.auxio.music.library.FakeLibrary
|
||||||
import org.oxycblt.auxio.music.model.Library
|
import org.oxycblt.auxio.music.library.Library
|
||||||
|
|
||||||
class MusicRepositoryTest {
|
class MusicRepositoryTest {
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -21,7 +21,7 @@ package org.oxycblt.auxio.music
|
||||||
import org.junit.Assert.assertEquals
|
import org.junit.Assert.assertEquals
|
||||||
import org.junit.Assert.assertTrue
|
import org.junit.Assert.assertTrue
|
||||||
import org.junit.Test
|
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.FakeIndexer
|
||||||
import org.oxycblt.auxio.music.system.Indexer
|
import org.oxycblt.auxio.music.system.Indexer
|
||||||
import org.oxycblt.auxio.util.forceClear
|
import org.oxycblt.auxio.util.forceClear
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.oxycblt.auxio.music.model
|
package org.oxycblt.auxio.music.library
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.net.Uri
|
import android.net.Uri
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.oxycblt.auxio.music.model
|
package org.oxycblt.auxio.music.library
|
||||||
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import org.junit.Assert.assertEquals
|
import org.junit.Assert.assertEquals
|
Loading…
Reference in a new issue