playback: add playlist support
Add playlist support to the playback code.
This commit is contained in:
parent
52e0620149
commit
f388e492aa
5 changed files with 66 additions and 30 deletions
|
@ -3,17 +3,16 @@
|
|||
## dev
|
||||
|
||||
#### What's New
|
||||
- Added support for `COMPILATION` and `ITUNESCOMPILATION` flags.
|
||||
- Added support for `COMPILATION` and `ITUNESCOMPILATION` flags
|
||||
|
||||
#### What's Improved
|
||||
- Accept `REPLAYGAIN_*` adjustment information on OPUS files alongside
|
||||
`R128_*` adjustments
|
||||
- List updates are now consistent across the app
|
||||
- Fixed jarring header update in detail view
|
||||
- Search view now trims search queries
|
||||
- Searching now ignores punctuation and trailing whitespace
|
||||
- Audio effect (equalizer) session is now broadcast when playing/pausing
|
||||
rather than on start/stop
|
||||
- Searching now ignores punctuation
|
||||
- Numeric names are now logically sorted (i.e 7 before 15)
|
||||
|
||||
#### What's Fixed
|
||||
|
|
|
@ -26,7 +26,6 @@ import androidx.fragment.app.activityViewModels
|
|||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.navigation.fragment.navArgs
|
||||
import androidx.recyclerview.widget.ConcatAdapter
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.material.transition.MaterialSharedAxis
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import org.oxycblt.auxio.R
|
||||
|
@ -114,16 +113,15 @@ class PlaylistDetailFragment :
|
|||
return true
|
||||
}
|
||||
|
||||
// TODO: Handle
|
||||
val currentPlaylist = unlikelyToBeNull(detailModel.currentPlaylist.value)
|
||||
return when (item.itemId) {
|
||||
R.id.action_play_next -> {
|
||||
// playbackModel.playNext(currentPlaylist)
|
||||
playbackModel.playNext(currentPlaylist)
|
||||
requireContext().showToast(R.string.lng_queue_added)
|
||||
true
|
||||
}
|
||||
R.id.action_queue_add -> {
|
||||
// playbackModel.addToQueue(currentPlaylist)
|
||||
playbackModel.addToQueue(currentPlaylist)
|
||||
requireContext().showToast(R.string.lng_queue_added)
|
||||
true
|
||||
}
|
||||
|
@ -131,12 +129,8 @@ class PlaylistDetailFragment :
|
|||
}
|
||||
}
|
||||
|
||||
override fun onClick(item: Song, viewHolder: RecyclerView.ViewHolder) {
|
||||
// TODO: Handle
|
||||
}
|
||||
|
||||
override fun onRealClick(item: Song) {
|
||||
// TODO: Handle
|
||||
playbackModel.playFromPlaylist(item, unlikelyToBeNull(detailModel.currentPlaylist.value))
|
||||
}
|
||||
|
||||
override fun onOpenMenu(item: Song, anchor: View) {
|
||||
|
@ -145,11 +139,11 @@ class PlaylistDetailFragment :
|
|||
|
||||
override fun onPlay() {
|
||||
// TODO: Handle
|
||||
// playbackModel.play(unlikelyToBeNull(detailModel.currentPlaylist.value))
|
||||
playbackModel.play(unlikelyToBeNull(detailModel.currentPlaylist.value))
|
||||
}
|
||||
|
||||
override fun onShuffle() {
|
||||
// playbackModel.shuffle(unlikelyToBeNull(detailModel.currentPlaylist.value))
|
||||
playbackModel.shuffle(unlikelyToBeNull(detailModel.currentPlaylist.value))
|
||||
}
|
||||
|
||||
override fun onOpenSortMenu(anchor: View) {
|
||||
|
|
|
@ -58,7 +58,7 @@ abstract class ListFragment<in T : Music, VB : ViewBinding> :
|
|||
*/
|
||||
abstract fun onRealClick(item: T)
|
||||
|
||||
override fun onClick(item: T, viewHolder: RecyclerView.ViewHolder) {
|
||||
final override fun onClick(item: T, viewHolder: RecyclerView.ViewHolder) {
|
||||
if (selectionModel.selected.value.isNotEmpty()) {
|
||||
// Map clicking an item to selecting an item when items are already selected.
|
||||
selectionModel.select(item)
|
||||
|
@ -68,7 +68,7 @@ abstract class ListFragment<in T : Music, VB : ViewBinding> :
|
|||
}
|
||||
}
|
||||
|
||||
override fun onSelect(item: T) {
|
||||
final override fun onSelect(item: T) {
|
||||
selectionModel.select(item)
|
||||
}
|
||||
|
||||
|
@ -222,26 +222,26 @@ abstract class ListFragment<in T : Music, VB : ViewBinding> :
|
|||
*
|
||||
* @param anchor The [View] to anchor the menu to.
|
||||
* @param menuRes The resource of the menu to load.
|
||||
* @param genre The [Playlist] to create the menu for.
|
||||
* @param playlist The [Playlist] to create the menu for.
|
||||
*/
|
||||
protected fun openMusicMenu(anchor: View, @MenuRes menuRes: Int, genre: Playlist) {
|
||||
logD("Launching new genre menu: ${genre.rawName}")
|
||||
protected fun openMusicMenu(anchor: View, @MenuRes menuRes: Int, playlist: Playlist) {
|
||||
logD("Launching new playlist menu: ${playlist.rawName}")
|
||||
|
||||
openMusicMenuImpl(anchor, menuRes) {
|
||||
when (it.itemId) {
|
||||
R.id.action_play -> {
|
||||
// playbackModel.play(genre)
|
||||
playbackModel.play(playlist)
|
||||
}
|
||||
R.id.action_shuffle -> {
|
||||
// playbackModel.shuffle(genre)
|
||||
playbackModel.shuffle(playlist)
|
||||
}
|
||||
R.id.action_play_next -> {
|
||||
// playbackModel.playNext(genre)
|
||||
// requireContext().showToast(R.string.lng_queue_added)
|
||||
playbackModel.playNext(playlist)
|
||||
requireContext().showToast(R.string.lng_queue_added)
|
||||
}
|
||||
R.id.action_queue_add -> {
|
||||
// playbackModel.addToQueue(genre)
|
||||
// requireContext().showToast(R.string.lng_queue_added)
|
||||
playbackModel.addToQueue(playlist)
|
||||
requireContext().showToast(R.string.lng_queue_added)
|
||||
}
|
||||
else -> {
|
||||
error("Unexpected menu item selected")
|
||||
|
|
|
@ -168,6 +168,7 @@ constructor(
|
|||
* - If [MusicMode.ALBUMS], the [Song] is played from it's [Album].
|
||||
* - If [MusicMode.ARTISTS], the [Song] is played from one of it's [Artist]s.
|
||||
* - If [MusicMode.GENRES], the [Song] is played from one of it's [Genre]s.
|
||||
* [MusicMode.PLAYLISTS] is disallowed here.
|
||||
*
|
||||
* @param song The [Song] to play.
|
||||
* @param playbackMode The [MusicMode] to play from.
|
||||
|
@ -200,7 +201,7 @@ constructor(
|
|||
}
|
||||
|
||||
/**
|
||||
* PLay a [Song] from one of it's [Genre]s.
|
||||
* Play a [Song] from one of it's [Genre]s.
|
||||
*
|
||||
* @param song The [Song] to play.
|
||||
* @param genre The [Genre] to play from. Must be linked to the [Song]. If null, the user will
|
||||
|
@ -216,6 +217,16 @@ constructor(
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* PLay a [Song] from one of it's [Playlist]s.
|
||||
*
|
||||
* @param song The [Song] to play.
|
||||
* @param playlist The [Playlist] to play from. Must be linked to the [Song].
|
||||
*/
|
||||
fun playFromPlaylist(song: Song, playlist: Playlist) {
|
||||
playImpl(song, playlist)
|
||||
}
|
||||
|
||||
/**
|
||||
* Play an [Album].
|
||||
*
|
||||
|
@ -237,6 +248,13 @@ constructor(
|
|||
*/
|
||||
fun play(genre: Genre) = playImpl(null, genre, false)
|
||||
|
||||
/**
|
||||
* Play a [Playlist].
|
||||
*
|
||||
* @param playlist The [Playlist] to play.
|
||||
*/
|
||||
fun play(playlist: Playlist) = playImpl(null, playlist, false)
|
||||
|
||||
/**
|
||||
* Play a [Music] selection.
|
||||
*
|
||||
|
@ -260,12 +278,19 @@ constructor(
|
|||
fun shuffle(artist: Artist) = playImpl(null, artist, true)
|
||||
|
||||
/**
|
||||
* Shuffle an [Genre].
|
||||
* Shuffle a [Genre].
|
||||
*
|
||||
* @param genre The [Genre] to shuffle.
|
||||
*/
|
||||
fun shuffle(genre: Genre) = playImpl(null, genre, true)
|
||||
|
||||
/**
|
||||
* Shuffle a [Playlist].
|
||||
*
|
||||
* @param playlist The [Playlist] to shuffle.
|
||||
*/
|
||||
fun shuffle(playlist: Playlist) = playImpl(null, playlist, true)
|
||||
|
||||
/**
|
||||
* Shuffle a [Music] selection.
|
||||
*
|
||||
|
@ -292,7 +317,7 @@ constructor(
|
|||
null -> musicSettings.songSort
|
||||
}
|
||||
val songs = parent?.songs ?: deviceLibrary.songs
|
||||
val queue = sort?.songs(songs) ?: songs
|
||||
val queue = sort.songs(songs)
|
||||
playbackManager.play(song, parent, queue, shuffled)
|
||||
}
|
||||
|
||||
|
@ -365,6 +390,15 @@ constructor(
|
|||
playbackManager.playNext(musicSettings.genreSongSort.songs(genre.songs))
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a [Playlist] to the top of the queue.
|
||||
*
|
||||
* @param playlist The [Playlist] to add.
|
||||
*/
|
||||
fun playNext(playlist: Playlist) {
|
||||
playbackManager.playNext(musicSettings.playlistSongSort.songs(playlist.songs))
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a selection to the top of the queue.
|
||||
*
|
||||
|
@ -410,6 +444,15 @@ constructor(
|
|||
playbackManager.addToQueue(musicSettings.genreSongSort.songs(genre.songs))
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a [Playlist] to the end of the queue.
|
||||
*
|
||||
* @param playlist The [Playlist] to add.
|
||||
*/
|
||||
fun addToQueue(playlist: Playlist) {
|
||||
playbackManager.addToQueue(musicSettings.playlistSongSort.songs(playlist.songs))
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a selection to the end of the queue.
|
||||
*
|
||||
|
@ -494,7 +537,7 @@ constructor(
|
|||
is Album -> musicSettings.albumSongSort.songs(it.songs)
|
||||
is Artist -> musicSettings.artistSongSort.songs(it.songs)
|
||||
is Genre -> musicSettings.genreSongSort.songs(it.songs)
|
||||
is Playlist -> musicSettings.playlistSongSort?.songs(it.songs) ?: it.songs
|
||||
is Playlist -> musicSettings.playlistSongSort.songs(it.songs)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ open class FakeMusicSettings : MusicSettings {
|
|||
set(_) = throw NotImplementedError()
|
||||
override var playlistSort: Sort
|
||||
get() = throw NotImplementedError()
|
||||
set(value) = throw NotImplementedError()
|
||||
set(_) = throw NotImplementedError()
|
||||
override var albumSongSort: Sort
|
||||
get() = throw NotImplementedError()
|
||||
set(_) = throw NotImplementedError()
|
||||
|
|
Loading…
Reference in a new issue