music: add playlist deletion
Add basic playlist deletion flow. No confirmation dialog yet, that will need to be implemented later.
This commit is contained in:
parent
956b6fda2b
commit
dcc82608bd
13 changed files with 92 additions and 37 deletions
|
@ -186,14 +186,11 @@ constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onMusicChanges(changes: MusicRepository.Changes) {
|
override fun onMusicChanges(changes: MusicRepository.Changes) {
|
||||||
if (!changes.deviceLibrary) return
|
|
||||||
val deviceLibrary = musicRepository.deviceLibrary ?: return
|
|
||||||
val userLibrary = musicRepository.userLibrary ?: return
|
|
||||||
|
|
||||||
// If we are showing any item right now, we will need to refresh it (and any information
|
// If we are showing any item right now, we will need to refresh it (and any information
|
||||||
// related to it) with the new library in order to prevent stale items from showing up
|
// related to it) with the new library in order to prevent stale items from showing up
|
||||||
// in the UI.
|
// in the UI.
|
||||||
|
val deviceLibrary = musicRepository.deviceLibrary
|
||||||
|
if (changes.deviceLibrary && deviceLibrary != null) {
|
||||||
val song = currentSong.value
|
val song = currentSong.value
|
||||||
if (song != null) {
|
if (song != null) {
|
||||||
_currentSong.value = deviceLibrary.findSong(song.uid)?.also(::refreshAudioInfo)
|
_currentSong.value = deviceLibrary.findSong(song.uid)?.also(::refreshAudioInfo)
|
||||||
|
@ -208,7 +205,8 @@ constructor(
|
||||||
|
|
||||||
val artist = currentArtist.value
|
val artist = currentArtist.value
|
||||||
if (artist != null) {
|
if (artist != null) {
|
||||||
_currentArtist.value = deviceLibrary.findArtist(artist.uid)?.also(::refreshArtistList)
|
_currentArtist.value =
|
||||||
|
deviceLibrary.findArtist(artist.uid)?.also(::refreshArtistList)
|
||||||
logD("Updated artist to ${currentArtist.value}")
|
logD("Updated artist to ${currentArtist.value}")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,13 +215,17 @@ constructor(
|
||||||
_currentGenre.value = deviceLibrary.findGenre(genre.uid)?.also(::refreshGenreList)
|
_currentGenre.value = deviceLibrary.findGenre(genre.uid)?.also(::refreshGenreList)
|
||||||
logD("Updated genre to ${currentGenre.value}")
|
logD("Updated genre to ${currentGenre.value}")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val userLibrary = musicRepository.userLibrary
|
||||||
|
if (changes.userLibrary && userLibrary != null) {
|
||||||
val playlist = currentPlaylist.value
|
val playlist = currentPlaylist.value
|
||||||
if (playlist != null) {
|
if (playlist != null) {
|
||||||
_currentPlaylist.value =
|
_currentPlaylist.value =
|
||||||
userLibrary.findPlaylist(playlist.uid)?.also(::refreshPlaylistList)
|
userLibrary.findPlaylist(playlist.uid)?.also(::refreshPlaylistList)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set a new [currentSong] from it's [Music.UID]. If the [Music.UID] differs, [currentSong] and
|
* Set a new [currentSong] from it's [Music.UID]. If the [Music.UID] differs, [currentSong] and
|
||||||
|
|
|
@ -126,6 +126,10 @@ class PlaylistDetailFragment :
|
||||||
requireContext().showToast(R.string.lng_queue_added)
|
requireContext().showToast(R.string.lng_queue_added)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
R.id.action_delete -> {
|
||||||
|
musicModel.deletePlaylist(currentPlaylist)
|
||||||
|
true
|
||||||
|
}
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -255,6 +255,9 @@ abstract class ListFragment<in T : Music, VB : ViewBinding> :
|
||||||
playbackModel.addToQueue(playlist)
|
playbackModel.addToQueue(playlist)
|
||||||
requireContext().showToast(R.string.lng_queue_added)
|
requireContext().showToast(R.string.lng_queue_added)
|
||||||
}
|
}
|
||||||
|
R.id.action_delete -> {
|
||||||
|
musicModel.deletePlaylist(playlist)
|
||||||
|
}
|
||||||
else -> {
|
else -> {
|
||||||
error("Unexpected menu item selected")
|
error("Unexpected menu item selected")
|
||||||
}
|
}
|
||||||
|
|
|
@ -350,8 +350,8 @@ interface Playlist : MusicParent {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run [Name.resolve] on each instance in the given list and concatenate them into a [String]
|
* Run [Name.resolve] on each instance in the given list and concatenate them into a [String] in a
|
||||||
* in a localized manner.
|
* localized manner.
|
||||||
*
|
*
|
||||||
* @param context [Context] required
|
* @param context [Context] required
|
||||||
* @return A concatenated string.
|
* @return A concatenated string.
|
||||||
|
|
|
@ -118,6 +118,13 @@ interface MusicRepository {
|
||||||
*/
|
*/
|
||||||
fun createPlaylist(name: String, songs: List<Song>)
|
fun createPlaylist(name: String, songs: List<Song>)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a [Playlist].
|
||||||
|
*
|
||||||
|
* @param playlist The playlist to delete.
|
||||||
|
*/
|
||||||
|
fun deletePlaylist(playlist: Playlist)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add the given [Song]s to a [Playlist].
|
* Add the given [Song]s to a [Playlist].
|
||||||
*
|
*
|
||||||
|
@ -262,6 +269,15 @@ constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun deletePlaylist(playlist: Playlist) {
|
||||||
|
val userLibrary = userLibrary ?: return
|
||||||
|
userLibrary.deletePlaylist(playlist)
|
||||||
|
for (listener in updateListeners) {
|
||||||
|
listener.onMusicChanges(
|
||||||
|
MusicRepository.Changes(deviceLibrary = false, userLibrary = true))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun addToPlaylist(songs: List<Song>, playlist: Playlist) {
|
override fun addToPlaylist(songs: List<Song>, playlist: Playlist) {
|
||||||
val userLibrary = userLibrary ?: return
|
val userLibrary = userLibrary ?: return
|
||||||
userLibrary.addToPlaylist(playlist, songs)
|
userLibrary.addToPlaylist(playlist, songs)
|
||||||
|
|
|
@ -106,6 +106,17 @@ constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a [Playlist].
|
||||||
|
*
|
||||||
|
* @param playlist The playlist to delete.
|
||||||
|
*
|
||||||
|
* TODO: Prompt the user before deleting.
|
||||||
|
*/
|
||||||
|
fun deletePlaylist(playlist: Playlist) {
|
||||||
|
musicRepository.deletePlaylist(playlist)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a [Song] to a [Playlist].
|
* Add a [Song] to a [Playlist].
|
||||||
*
|
*
|
||||||
|
|
|
@ -210,6 +210,8 @@ private class DeviceLibraryImpl(rawSongs: List<RawSong>, settings: MusicSettings
|
||||||
albums: List<AlbumImpl>,
|
albums: List<AlbumImpl>,
|
||||||
settings: MusicSettings
|
settings: MusicSettings
|
||||||
): List<ArtistImpl> {
|
): List<ArtistImpl> {
|
||||||
|
// TODO: Debug an issue with my current library config that results in two duplicate
|
||||||
|
// artists.
|
||||||
// Add every raw artist credited to each Song/Album to the grouping. This way,
|
// Add every raw artist credited to each Song/Album to the grouping. This way,
|
||||||
// different multi-artist combinations are not treated as different artists.
|
// different multi-artist combinations are not treated as different artists.
|
||||||
val musicByArtist = mutableMapOf<RawArtist, MutableList<Music>>()
|
val musicByArtist = mutableMapOf<RawArtist, MutableList<Music>>()
|
||||||
|
|
|
@ -99,11 +99,6 @@ class SeparatorsDialog : ViewBindingDialogFragment<DialogSeparatorsBinding>() {
|
||||||
return separators
|
return separators
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Defines the allowed separator characters that can be used to delimit multi-value tags.
|
|
||||||
*
|
|
||||||
* @author Alexander Capehart (OxygenCobalt)
|
|
||||||
*/
|
|
||||||
private object Separators {
|
private object Separators {
|
||||||
const val COMMA = ','
|
const val COMMA = ','
|
||||||
const val SEMICOLON = ';'
|
const val SEMICOLON = ';'
|
||||||
|
|
|
@ -130,6 +130,9 @@ private class TagWorkerImpl(
|
||||||
// 3. ID3v2.4 Release Date, as it is the second most common date type
|
// 3. ID3v2.4 Release Date, as it is the second most common date type
|
||||||
// 4. ID3v2.3 Original Date, as it is like #1
|
// 4. ID3v2.3 Original Date, as it is like #1
|
||||||
// 5. ID3v2.3 Release Year, as it is the most common date type
|
// 5. ID3v2.3 Release Year, as it is the most common date type
|
||||||
|
// TODO: Show original and normal dates side-by-side
|
||||||
|
// TODO: Handle dates that are in "January" because the actual specific release date
|
||||||
|
// isn't known?
|
||||||
(textFrames["TDOR"]?.run { Date.from(first()) }
|
(textFrames["TDOR"]?.run { Date.from(first()) }
|
||||||
?: textFrames["TDRC"]?.run { Date.from(first()) }
|
?: textFrames["TDRC"]?.run { Date.from(first()) }
|
||||||
?: textFrames["TDRL"]?.run { Date.from(first()) }
|
?: textFrames["TDRL"]?.run { Date.from(first()) }
|
||||||
|
|
|
@ -80,6 +80,13 @@ interface MutableUserLibrary : UserLibrary {
|
||||||
*/
|
*/
|
||||||
fun createPlaylist(name: String, songs: List<Song>)
|
fun createPlaylist(name: String, songs: List<Song>)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a [Playlist].
|
||||||
|
*
|
||||||
|
* @param playlist The playlist to delete.
|
||||||
|
*/
|
||||||
|
fun deletePlaylist(playlist: Playlist)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add [Song]s to a [Playlist].
|
* Add [Song]s to a [Playlist].
|
||||||
*
|
*
|
||||||
|
@ -120,6 +127,11 @@ private class UserLibraryImpl(
|
||||||
playlistMap[playlistImpl.uid] = playlistImpl
|
playlistMap[playlistImpl.uid] = playlistImpl
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Synchronized
|
||||||
|
override fun deletePlaylist(playlist: Playlist) {
|
||||||
|
playlistMap.remove(playlist.uid)
|
||||||
|
}
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
override fun addToPlaylist(playlist: Playlist, songs: List<Song>) {
|
override fun addToPlaylist(playlist: Playlist, songs: List<Song>) {
|
||||||
val playlistImpl =
|
val playlistImpl =
|
||||||
|
|
|
@ -12,4 +12,7 @@
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_queue_add"
|
android:id="@+id/action_queue_add"
|
||||||
android:title="@string/lbl_queue_add" />
|
android:title="@string/lbl_queue_add" />
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_delete"
|
||||||
|
android:title="@string/lbl_delete" />
|
||||||
</menu>
|
</menu>
|
|
@ -6,4 +6,7 @@
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_queue_add"
|
android:id="@+id/action_queue_add"
|
||||||
android:title="@string/lbl_queue_add" />
|
android:title="@string/lbl_queue_add" />
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_delete"
|
||||||
|
android:title="@string/lbl_delete" />
|
||||||
</menu>
|
</menu>
|
|
@ -79,6 +79,7 @@
|
||||||
<string name="lbl_playlist">Playlist</string>
|
<string name="lbl_playlist">Playlist</string>
|
||||||
<string name="lbl_playlists">Playlists</string>
|
<string name="lbl_playlists">Playlists</string>
|
||||||
<string name="lbl_new_playlist">New playlist</string>
|
<string name="lbl_new_playlist">New playlist</string>
|
||||||
|
<string name="lbl_delete">Delete</string>
|
||||||
|
|
||||||
<!-- Search for music -->
|
<!-- Search for music -->
|
||||||
<string name="lbl_search">Search</string>
|
<string name="lbl_search">Search</string>
|
||||||
|
|
Loading…
Reference in a new issue