diff --git a/CHANGELOG.md b/CHANGELOG.md index df765a896..31c416554 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/app/src/main/java/org/oxycblt/auxio/detail/PlaylistDetailFragment.kt b/app/src/main/java/org/oxycblt/auxio/detail/PlaylistDetailFragment.kt index e0b145b04..f0e8e64ba 100644 --- a/app/src/main/java/org/oxycblt/auxio/detail/PlaylistDetailFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/detail/PlaylistDetailFragment.kt @@ -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) { diff --git a/app/src/main/java/org/oxycblt/auxio/list/ListFragment.kt b/app/src/main/java/org/oxycblt/auxio/list/ListFragment.kt index 31aef6c1e..c30909c33 100644 --- a/app/src/main/java/org/oxycblt/auxio/list/ListFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/list/ListFragment.kt @@ -58,7 +58,7 @@ abstract class ListFragment : */ 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 : } } - override fun onSelect(item: T) { + final override fun onSelect(item: T) { selectionModel.select(item) } @@ -222,26 +222,26 @@ abstract class ListFragment : * * @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") 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 2b3d43e9e..d94e38621 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackViewModel.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackViewModel.kt @@ -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) } } } diff --git a/app/src/test/java/org/oxycblt/auxio/music/FakeMusicSettings.kt b/app/src/test/java/org/oxycblt/auxio/music/FakeMusicSettings.kt index 757fd69fc..3aee23131 100644 --- a/app/src/test/java/org/oxycblt/auxio/music/FakeMusicSettings.kt +++ b/app/src/test/java/org/oxycblt/auxio/music/FakeMusicSettings.kt @@ -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()