From 9e5b737d1a2605f311a66e36a4e9db74f5696c3e Mon Sep 17 00:00:00 2001 From: Alexander Capehart Date: Tue, 4 Jul 2023 14:24:46 -0600 Subject: [PATCH] playback: refactor navigation commands Unify the artist and genre picker commands into a single event (like others), and also make the playback panel correctly respond to album/artist navigation events. --- .../java/org/oxycblt/auxio/MainFragment.kt | 10 +-- .../auxio/detail/AlbumDetailFragment.kt | 34 +++++---- .../auxio/detail/ArtistDetailFragment.kt | 32 ++++---- .../auxio/detail/GenreDetailFragment.kt | 29 ++++---- .../auxio/detail/PlaylistDetailFragment.kt | 29 +++++--- .../auxio/detail/picker/ShowArtistDialog.kt | 4 +- .../auxio/playback/PlaybackPanelFragment.kt | 27 +++++-- .../auxio/playback/PlaybackViewModel.kt | 66 ++++++++--------- .../playback/picker/PlayFromArtistDialog.kt | 20 +++-- .../playback/picker/PlayFromGenreDialog.kt | 20 +++-- .../oxycblt/auxio/search/SearchFragment.kt | 74 ++++++++++++------- 11 files changed, 197 insertions(+), 148 deletions(-) diff --git a/app/src/main/java/org/oxycblt/auxio/MainFragment.kt b/app/src/main/java/org/oxycblt/auxio/MainFragment.kt index 3538b4235..72c9c4d9c 100644 --- a/app/src/main/java/org/oxycblt/auxio/MainFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/MainFragment.kt @@ -42,7 +42,7 @@ import org.oxycblt.auxio.detail.DetailViewModel import org.oxycblt.auxio.list.selection.SelectionViewModel import org.oxycblt.auxio.music.Music import org.oxycblt.auxio.music.Song -import org.oxycblt.auxio.playback.Panel +import org.oxycblt.auxio.playback.OpenPanel import org.oxycblt.auxio.playback.PlaybackBottomSheetBehavior import org.oxycblt.auxio.playback.PlaybackViewModel import org.oxycblt.auxio.playback.queue.QueueBottomSheetBehavior @@ -300,13 +300,13 @@ class MainFragment : } } - private fun handlePanel(panel: Panel?) { + private fun handlePanel(panel: OpenPanel?) { if (panel == null) return logD("Trying to update panel to $panel") when (panel) { - is Panel.Main -> tryClosePlaybackPanel() - is Panel.Playback -> tryOpenPlaybackPanel() - is Panel.Queue -> tryOpenQueuePanel() + is OpenPanel.Main -> tryClosePlaybackPanel() + is OpenPanel.Playback -> tryOpenPlaybackPanel() + is OpenPanel.Queue -> tryOpenQueuePanel() } playbackModel.openPanel.consume() } diff --git a/app/src/main/java/org/oxycblt/auxio/detail/AlbumDetailFragment.kt b/app/src/main/java/org/oxycblt/auxio/detail/AlbumDetailFragment.kt index 8b6da9d08..26545af8f 100644 --- a/app/src/main/java/org/oxycblt/auxio/detail/AlbumDetailFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/detail/AlbumDetailFragment.kt @@ -51,6 +51,7 @@ import org.oxycblt.auxio.music.MusicViewModel import org.oxycblt.auxio.music.PlaylistDecision import org.oxycblt.auxio.music.Song import org.oxycblt.auxio.music.info.Disc +import org.oxycblt.auxio.playback.PlaybackDecision import org.oxycblt.auxio.playback.PlaybackViewModel import org.oxycblt.auxio.util.canScroll import org.oxycblt.auxio.util.collect @@ -129,11 +130,10 @@ class AlbumDetailFragment : collect(detailModel.toShow.flow, ::handleShow) collect(menuModel.pendingMenu.flow, ::handleMenu) collectImmediately(selectionModel.selected, ::updateSelection) - collect(musicModel.playlistDecision.flow, ::handleDecision) + collect(musicModel.playlistDecision.flow, ::handlePlaylistDecision) collectImmediately( playbackModel.song, playbackModel.parent, playbackModel.isPlaying, ::updatePlayback) - collect(playbackModel.artistPickerSong.flow, ::handlePlayFromArtist) - collect(playbackModel.genrePickerSong.flow, ::handlePlayFromGenre) + collect(playbackModel.playbackDecision.flow, ::handlePlaybackDecision) } override fun onDestroyBinding(binding: FragmentDetailBinding) { @@ -331,7 +331,7 @@ class AlbumDetailFragment : } } - private fun handleDecision(decision: PlaylistDecision?) { + private fun handlePlaylistDecision(decision: PlaylistDecision?) { if (decision == null) return val directions = when (decision) { @@ -342,7 +342,7 @@ class AlbumDetailFragment : } is PlaylistDecision.New, is PlaylistDecision.Rename, - is PlaylistDecision.Delete -> error("Unexpected decision $decision") + is PlaylistDecision.Delete -> error("Unexpected playlist decision $decision") } findNavController().navigateSafe(directions) } @@ -352,16 +352,20 @@ class AlbumDetailFragment : song.takeIf { parent == detailModel.currentAlbum.value }, isPlaying) } - private fun handlePlayFromArtist(song: Song?) { - if (song == null) return - logD("Launching play from artist dialog for $song") - findNavController().navigateSafe(AlbumDetailFragmentDirections.playFromArtist(song.uid)) - } - - private fun handlePlayFromGenre(song: Song?) { - if (song == null) return - logD("Launching play from genre dialog for $song") - findNavController().navigateSafe(AlbumDetailFragmentDirections.playFromGenre(song.uid)) + private fun handlePlaybackDecision(decision: PlaybackDecision?) { + if (decision == null) return + val directions = + when (decision) { + is PlaybackDecision.PlayFromArtist -> { + logD("Launching play from artist dialog for $decision") + AlbumDetailFragmentDirections.playFromArtist(decision.song.uid) + } + is PlaybackDecision.PlayFromGenre -> { + logD("Launching play from artist dialog for $decision") + AlbumDetailFragmentDirections.playFromGenre(decision.song.uid) + } + } + findNavController().navigateSafe(directions) } private fun scrollToAlbumSong(song: Song) { diff --git a/app/src/main/java/org/oxycblt/auxio/detail/ArtistDetailFragment.kt b/app/src/main/java/org/oxycblt/auxio/detail/ArtistDetailFragment.kt index 5d3ab0a75..c133f26ad 100644 --- a/app/src/main/java/org/oxycblt/auxio/detail/ArtistDetailFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/detail/ArtistDetailFragment.kt @@ -50,6 +50,7 @@ import org.oxycblt.auxio.music.MusicParent import org.oxycblt.auxio.music.MusicViewModel import org.oxycblt.auxio.music.PlaylistDecision import org.oxycblt.auxio.music.Song +import org.oxycblt.auxio.playback.PlaybackDecision import org.oxycblt.auxio.playback.PlaybackViewModel import org.oxycblt.auxio.util.collect import org.oxycblt.auxio.util.collectImmediately @@ -130,11 +131,10 @@ class ArtistDetailFragment : collect(detailModel.toShow.flow, ::handleShow) collect(menuModel.pendingMenu.flow, ::handleMenu) collectImmediately(selectionModel.selected, ::updateSelection) - collect(musicModel.playlistDecision.flow, ::handleDecision) + collect(musicModel.playlistDecision.flow, ::handlePlaylistDecision) collectImmediately( playbackModel.song, playbackModel.parent, playbackModel.isPlaying, ::updatePlayback) - collect(playbackModel.artistPickerSong.flow, ::handlePlayFromArtist) - collect(playbackModel.genrePickerSong.flow, ::handlePlayFromGenre) + collect(playbackModel.playbackDecision.flow, ::handlePlaybackDecision) } override fun onDestroyBinding(binding: FragmentDetailBinding) { @@ -343,7 +343,7 @@ class ArtistDetailFragment : } } - private fun handleDecision(decision: PlaylistDecision?) { + private fun handlePlaylistDecision(decision: PlaylistDecision?) { if (decision == null) return val directions = when (decision) { @@ -354,7 +354,7 @@ class ArtistDetailFragment : } is PlaylistDecision.New, is PlaylistDecision.Rename, - is PlaylistDecision.Delete -> error("Unexpected decision $decision") + is PlaylistDecision.Delete -> error("Unexpected playlist decision $decision") } findNavController().navigateSafe(directions) } @@ -374,15 +374,17 @@ class ArtistDetailFragment : artistListAdapter.setPlaying(playingItem, isPlaying) } - private fun handlePlayFromArtist(song: Song?) { - if (song == null) return - logD("Launching play from artist dialog for $song") - findNavController().navigateSafe(AlbumDetailFragmentDirections.playFromArtist(song.uid)) - } - - private fun handlePlayFromGenre(song: Song?) { - if (song == null) return - logD("Launching play from genre dialog for $song") - findNavController().navigateSafe(AlbumDetailFragmentDirections.playFromGenre(song.uid)) + private fun handlePlaybackDecision(decision: PlaybackDecision?) { + if (decision == null) return + val directions = + when (decision) { + is PlaybackDecision.PlayFromArtist -> + error("Unexpected playback decision $decision") + is PlaybackDecision.PlayFromGenre -> { + logD("Launching play from artist dialog for $decision") + ArtistDetailFragmentDirections.playFromGenre(decision.song.uid) + } + } + findNavController().navigateSafe(directions) } } 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 8d299c448..51527b5f8 100644 --- a/app/src/main/java/org/oxycblt/auxio/detail/GenreDetailFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/detail/GenreDetailFragment.kt @@ -50,6 +50,7 @@ import org.oxycblt.auxio.music.MusicParent import org.oxycblt.auxio.music.MusicViewModel import org.oxycblt.auxio.music.PlaylistDecision import org.oxycblt.auxio.music.Song +import org.oxycblt.auxio.playback.PlaybackDecision import org.oxycblt.auxio.playback.PlaybackViewModel import org.oxycblt.auxio.util.collect import org.oxycblt.auxio.util.collectImmediately @@ -131,8 +132,7 @@ class GenreDetailFragment : collect(musicModel.playlistDecision.flow, ::handleDecision) collectImmediately( playbackModel.song, playbackModel.parent, playbackModel.isPlaying, ::updatePlayback) - collect(playbackModel.artistPickerSong.flow, ::handlePlayFromArtist) - collect(playbackModel.genrePickerSong.flow, ::handlePlayFromGenre) + collect(playbackModel.playbackDecision.flow, ::handlePlaybackDecision) } override fun onDestroyBinding(binding: FragmentDetailBinding) { @@ -337,12 +337,12 @@ class GenreDetailFragment : when (decision) { is PlaylistDecision.Add -> { logD("Adding ${decision.songs.size} songs to a playlist") - ArtistDetailFragmentDirections.addToPlaylist( + GenreDetailFragmentDirections.addToPlaylist( decision.songs.map { it.uid }.toTypedArray()) } is PlaylistDecision.New, is PlaylistDecision.Rename, - is PlaylistDecision.Delete -> error("Unexpected decision $decision") + is PlaylistDecision.Delete -> error("Unexpected playlist decision $decision") } findNavController().navigateSafe(directions) } @@ -362,15 +362,16 @@ class GenreDetailFragment : genreListAdapter.setPlaying(playingItem, isPlaying) } - private fun handlePlayFromArtist(song: Song?) { - if (song == null) return - logD("Launching play from artist dialog for $song") - findNavController().navigateSafe(AlbumDetailFragmentDirections.playFromArtist(song.uid)) - } - - private fun handlePlayFromGenre(song: Song?) { - if (song == null) return - logD("Launching play from genre dialog for $song") - findNavController().navigateSafe(AlbumDetailFragmentDirections.playFromGenre(song.uid)) + private fun handlePlaybackDecision(decision: PlaybackDecision?) { + if (decision == null) return + val directions = + when (decision) { + is PlaybackDecision.PlayFromArtist -> { + logD("Launching play from artist dialog for $decision") + GenreDetailFragmentDirections.playFromArtist(decision.song.uid) + } + is PlaybackDecision.PlayFromGenre -> error("Unexpected playback decision $decision") + } + findNavController().navigateSafe(directions) } } 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 f27164c85..28eb68127 100644 --- a/app/src/main/java/org/oxycblt/auxio/detail/PlaylistDetailFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/detail/PlaylistDetailFragment.kt @@ -52,6 +52,7 @@ import org.oxycblt.auxio.music.MusicViewModel import org.oxycblt.auxio.music.Playlist import org.oxycblt.auxio.music.PlaylistDecision import org.oxycblt.auxio.music.Song +import org.oxycblt.auxio.playback.PlaybackDecision import org.oxycblt.auxio.playback.PlaybackViewModel import org.oxycblt.auxio.util.collect import org.oxycblt.auxio.util.collectImmediately @@ -146,8 +147,7 @@ class PlaylistDetailFragment : collect(musicModel.playlistDecision.flow, ::handleDecision) collectImmediately( playbackModel.song, playbackModel.parent, playbackModel.isPlaying, ::updatePlayback) - collect(playbackModel.artistPickerSong.flow, ::handlePlayFromArtist) - collect(playbackModel.genrePickerSong.flow, ::handlePlayFromGenre) + collect(playbackModel.playbackDecision.flow, ::handlePlaybackDecision) } override fun onStart() { @@ -387,7 +387,7 @@ class PlaylistDetailFragment : PlaylistDetailFragmentDirections.deletePlaylist(decision.playlist.uid) } is PlaylistDecision.Add, - is PlaylistDecision.New -> error("Unexpected decision $decision") + is PlaylistDecision.New -> error("Unexpected playlist decision $decision") } findNavController().navigateSafe(directions) } @@ -398,17 +398,22 @@ class PlaylistDetailFragment : song.takeIf { parent == detailModel.currentPlaylist.value }, isPlaying) } - private fun handlePlayFromArtist(song: Song?) { - if (song == null) return - logD("Launching play from artist dialog for $song") - findNavController().navigateSafe(AlbumDetailFragmentDirections.playFromArtist(song.uid)) + private fun handlePlaybackDecision(decision: PlaybackDecision?) { + if (decision == null) return + val directions = + when (decision) { + is PlaybackDecision.PlayFromArtist -> { + logD("Launching play from artist dialog for $decision") + PlaylistDetailFragmentDirections.playFromArtist(decision.song.uid) + } + is PlaybackDecision.PlayFromGenre -> { + logD("Launching play from artist dialog for $decision") + PlaylistDetailFragmentDirections.playFromGenre(decision.song.uid) + } + } + findNavController().navigateSafe(directions) } - private fun handlePlayFromGenre(song: Song?) { - if (song == null) return - logD("Launching play from genre dialog for $song") - findNavController().navigateSafe(AlbumDetailFragmentDirections.playFromGenre(song.uid)) - } private fun updateMultiToolbar() { val id = when { diff --git a/app/src/main/java/org/oxycblt/auxio/detail/picker/ShowArtistDialog.kt b/app/src/main/java/org/oxycblt/auxio/detail/picker/ShowArtistDialog.kt index c8b58f40d..3f17ed888 100644 --- a/app/src/main/java/org/oxycblt/auxio/detail/picker/ShowArtistDialog.kt +++ b/app/src/main/java/org/oxycblt/auxio/detail/picker/ShowArtistDialog.kt @@ -69,7 +69,7 @@ class ShowArtistDialog : detailModel.toShow.consume() pickerModel.setArtistChoiceUid(args.itemUid) - collectImmediately(pickerModel.artistChoices, ::handleChoices) + collectImmediately(pickerModel.artistChoices, ::updateChoices) } override fun onDestroyBinding(binding: DialogMusicChoicesBinding) { @@ -83,7 +83,7 @@ class ShowArtistDialog : detailModel.showArtist(item) } - private fun handleChoices(choices: ArtistShowChoices?) { + private fun updateChoices(choices: ArtistShowChoices?) { if (choices == null) { logD("No choices to show, navigating away") findNavController().navigateUp() diff --git a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackPanelFragment.kt b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackPanelFragment.kt index a12cb389b..20f8802a0 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackPanelFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackPanelFragment.kt @@ -33,6 +33,7 @@ import dagger.hilt.android.AndroidEntryPoint import org.oxycblt.auxio.R import org.oxycblt.auxio.databinding.FragmentPlaybackPanelBinding import org.oxycblt.auxio.detail.DetailViewModel +import org.oxycblt.auxio.detail.Show import org.oxycblt.auxio.music.MusicParent import org.oxycblt.auxio.music.MusicViewModel import org.oxycblt.auxio.music.Song @@ -40,6 +41,7 @@ import org.oxycblt.auxio.music.resolveNames import org.oxycblt.auxio.playback.state.RepeatMode import org.oxycblt.auxio.playback.ui.StyledSeekBar import org.oxycblt.auxio.ui.ViewBindingFragment +import org.oxycblt.auxio.util.collect import org.oxycblt.auxio.util.collectImmediately import org.oxycblt.auxio.util.logD import org.oxycblt.auxio.util.share @@ -129,6 +131,7 @@ class PlaybackPanelFragment : collectImmediately(playbackModel.repeatMode, ::updateRepeat) collectImmediately(playbackModel.isPlaying, ::updatePlaying) collectImmediately(playbackModel.isShuffled, ::updateShuffled) + collect(detailModel.toShow.flow, ::handleShow) } override fun onDestroyBinding(binding: FragmentPlaybackPanelBinding) { @@ -233,17 +236,25 @@ class PlaybackPanelFragment : requireBinding().playbackShuffle.isActivated = isShuffled } - private fun navigateToCurrentArtist() { - playbackModel.song.value?.let { - detailModel.showArtist(it) - playbackModel.openMain() + private fun handleShow(show: Show?) { + when (show) { + is Show.ArtistDetails, + is Show.AlbumDetails -> playbackModel.openMain() + is Show.SongDetails, + is Show.SongAlbumDetails, + is Show.SongArtistDetails, + is Show.AlbumArtistDetails, + is Show.GenreDetails, + is Show.PlaylistDetails, + null -> {} } } + private fun navigateToCurrentArtist() { + playbackModel.song.value?.let(detailModel::showArtist) + } + private fun navigateToCurrentAlbum() { - playbackModel.song.value?.let { - detailModel.showAlbum(it.album) - playbackModel.openMain() - } + playbackModel.song.value?.let { detailModel.showAlbum(it.album) } } } 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 ea6b7b53a..229ef373a 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackViewModel.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackViewModel.kt @@ -89,31 +89,15 @@ constructor( val isShuffled: StateFlow get() = _isShuffled - private val _openPanel = MutableEvent() - val openPanel: Event + val currentBarAction: ActionMode = playbackSettings.barAction + + private val _openPanel = MutableEvent() + val openPanel: Event get() = _openPanel - private val _artistPlaybackPickerSong = MutableEvent() - /** - * Flag signaling to open a picker dialog in order to resolve an ambiguous choice when playing a - * [Song] from one of it's [Artist]s. - * - * @see playFromArtist - */ - val artistPickerSong: Event - get() = _artistPlaybackPickerSong - - private val _genrePlaybackPickerSong = MutableEvent() - /** - * Flag signaling to open a picker dialog in order to resolve an ambiguous choice when playing a - * [Song] from one of it's [Genre]s. - */ - val genrePickerSong: Event - get() = _genrePlaybackPickerSong - - /** The current action to show on the playback bar. */ - val currentBarAction: ActionMode - get() = playbackSettings.barAction + private val _playbackDecision = MutableEvent() + val playbackDecision: Event + get() = _playbackDecision /** * The current audio session ID of the internal player. Null if no [InternalPlayer] is @@ -223,7 +207,7 @@ constructor( playImpl(song, song.artists[0]) } else { logD("$song has multiple artists, showing choice dialog") - _artistPlaybackPickerSong.put(song) + startPlaybackDecisionImpl(PlaybackDecision.PlayFromArtist(song)) } } @@ -243,10 +227,19 @@ constructor( playImpl(song, song.genres[0]) } else { logD("$song has multiple genres, showing choice dialog") - _genrePlaybackPickerSong.put(song) + startPlaybackDecisionImpl(PlaybackDecision.PlayFromGenre(song)) } } + private fun startPlaybackDecisionImpl(decision: PlaybackDecision) { + val existing = _playbackDecision.flow.value + if (existing != null) { + logD("Already handling decision $existing, ignoring $decision") + return + } + _playbackDecision.put(decision) + } + /** * PLay a [Song] from one of it's [Playlist]s. * @@ -560,11 +553,11 @@ constructor( } // --- UI CONTROL --- - fun openMain() = openImpl(Panel.Main) - fun openPlayback() = openImpl(Panel.Playback) - fun openQueue() = openImpl(Panel.Queue) + fun openMain() = openImpl(OpenPanel.Main) + fun openPlayback() = openImpl(OpenPanel.Playback) + fun openQueue() = openImpl(OpenPanel.Queue) - private fun openImpl(panel: Panel) { + private fun openImpl(panel: OpenPanel) { val existing = openPanel.flow.value if (existing != null) { logD("Already opening $existing, ignoring opening $panel") @@ -617,8 +610,15 @@ constructor( } } -sealed interface Panel { - object Main : Panel - object Playback : Panel - object Queue : Panel +sealed interface OpenPanel { + object Main : OpenPanel + object Playback : OpenPanel + object Queue : OpenPanel +} + +sealed interface PlaybackDecision { + val song: Song + + class PlayFromArtist(override val song: Song) : PlaybackDecision + class PlayFromGenre(override val song: Song) : PlaybackDecision } diff --git a/app/src/main/java/org/oxycblt/auxio/playback/picker/PlayFromArtistDialog.kt b/app/src/main/java/org/oxycblt/auxio/playback/picker/PlayFromArtistDialog.kt index 1c7f025ef..2713fc934 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/picker/PlayFromArtistDialog.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/picker/PlayFromArtistDialog.kt @@ -32,6 +32,7 @@ import org.oxycblt.auxio.databinding.DialogMusicChoicesBinding import org.oxycblt.auxio.list.ClickableListListener import org.oxycblt.auxio.list.adapter.UpdateInstructions import org.oxycblt.auxio.music.Artist +import org.oxycblt.auxio.music.Song import org.oxycblt.auxio.playback.PlaybackViewModel import org.oxycblt.auxio.ui.ViewBindingMaterialDialogFragment import org.oxycblt.auxio.util.collectImmediately @@ -68,15 +69,9 @@ class PlayFromArtistDialog : adapter = choiceAdapter } + playbackModel.playbackDecision.consume() pickerModel.setPickerSongUid(args.artistUid) - collectImmediately(pickerModel.currentPickerSong) { - if (it != null) { - choiceAdapter.update(it.artists, UpdateInstructions.Replace(0)) - } else { - logD("No song to show choices for, navigating away") - findNavController().navigateUp() - } - } + collectImmediately(pickerModel.currentPickerSong, ::updateSong) } override fun onDestroyBinding(binding: DialogMusicChoicesBinding) { @@ -90,4 +85,13 @@ class PlayFromArtistDialog : playbackModel.playFromArtist(song, item) findNavController().navigateUp() } + + private fun updateSong(song: Song?) { + if (song == null) { + logD("No song to show choices for, navigating away") + findNavController().navigateUp() + return + } + choiceAdapter.update(song.artists, UpdateInstructions.Replace(0)) + } } diff --git a/app/src/main/java/org/oxycblt/auxio/playback/picker/PlayFromGenreDialog.kt b/app/src/main/java/org/oxycblt/auxio/playback/picker/PlayFromGenreDialog.kt index e47f87968..0c0ac9ba0 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/picker/PlayFromGenreDialog.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/picker/PlayFromGenreDialog.kt @@ -32,6 +32,7 @@ import org.oxycblt.auxio.databinding.DialogMusicChoicesBinding import org.oxycblt.auxio.list.ClickableListListener import org.oxycblt.auxio.list.adapter.UpdateInstructions import org.oxycblt.auxio.music.Genre +import org.oxycblt.auxio.music.Song import org.oxycblt.auxio.playback.PlaybackViewModel import org.oxycblt.auxio.ui.ViewBindingMaterialDialogFragment import org.oxycblt.auxio.util.collectImmediately @@ -68,15 +69,9 @@ class PlayFromGenreDialog : adapter = choiceAdapter } + playbackModel.playbackDecision.consume() pickerModel.setPickerSongUid(args.genreUid) - collectImmediately(pickerModel.currentPickerSong) { - if (it != null) { - choiceAdapter.update(it.genres, UpdateInstructions.Replace(0)) - } else { - logD("No song to show choices for, navigating away") - findNavController().navigateUp() - } - } + collectImmediately(pickerModel.currentPickerSong, ::updateSong) } override fun onDestroyBinding(binding: DialogMusicChoicesBinding) { @@ -90,4 +85,13 @@ class PlayFromGenreDialog : playbackModel.playFromGenre(song, item) findNavController().navigateUp() } + + private fun updateSong(song: Song?) { + if (song == null) { + logD("No song to show choices for, navigating away") + findNavController().navigateUp() + return + } + choiceAdapter.update(song.genres, UpdateInstructions.Replace(0)) + } } 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 614a48819..432581600 100644 --- a/app/src/main/java/org/oxycblt/auxio/search/SearchFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/search/SearchFragment.kt @@ -52,6 +52,7 @@ import org.oxycblt.auxio.music.MusicViewModel import org.oxycblt.auxio.music.Playlist import org.oxycblt.auxio.music.PlaylistDecision import org.oxycblt.auxio.music.Song +import org.oxycblt.auxio.playback.PlaybackDecision import org.oxycblt.auxio.playback.PlaybackViewModel import org.oxycblt.auxio.util.collect import org.oxycblt.auxio.util.collectImmediately @@ -145,6 +146,7 @@ class SearchFragment : ListFragment() { collect(musicModel.playlistDecision.flow, ::handleDecision) collectImmediately( playbackModel.song, playbackModel.parent, playbackModel.isPlaying, ::updatePlayback) + collect(playbackModel.playbackDecision.flow, ::handlePlaybackDecision) collect(detailModel.toShow.flow, ::handleShow) } @@ -260,34 +262,6 @@ class SearchFragment : ListFragment() { hideKeyboard() } - private fun handleDecision(decision: PlaylistDecision?) { - if (decision == null) return - val directions = - when (decision) { - is PlaylistDecision.Rename -> { - logD("Renaming ${decision.playlist}") - SearchFragmentDirections.renamePlaylist(decision.playlist.uid) - } - is PlaylistDecision.Delete -> { - logD("Deleting ${decision.playlist}") - SearchFragmentDirections.deletePlaylist(decision.playlist.uid) - } - is PlaylistDecision.Add -> { - logD("Adding ${decision.songs.size} to a playlist") - SearchFragmentDirections.addToPlaylist( - decision.songs.map { it.uid }.toTypedArray()) - } - is PlaylistDecision.New -> { - error("Unexpected decision $decision") - } - } - findNavController().navigateSafe(directions) - } - - private fun updatePlayback(song: Song?, parent: MusicParent?, isPlaying: Boolean) { - searchAdapter.setPlaying(parent ?: song, isPlaying) - } - private fun handleMenu(pendingMenu: PendingMenu?) { if (pendingMenu == null) return val directions = @@ -326,6 +300,50 @@ class SearchFragment : ListFragment() { } } + private fun handleDecision(decision: PlaylistDecision?) { + if (decision == null) return + val directions = + when (decision) { + is PlaylistDecision.Rename -> { + logD("Renaming ${decision.playlist}") + SearchFragmentDirections.renamePlaylist(decision.playlist.uid) + } + is PlaylistDecision.Delete -> { + logD("Deleting ${decision.playlist}") + SearchFragmentDirections.deletePlaylist(decision.playlist.uid) + } + is PlaylistDecision.Add -> { + logD("Adding ${decision.songs.size} to a playlist") + SearchFragmentDirections.addToPlaylist( + decision.songs.map { it.uid }.toTypedArray()) + } + is PlaylistDecision.New -> { + error("Unexpected decision $decision") + } + } + findNavController().navigateSafe(directions) + } + + private fun updatePlayback(song: Song?, parent: MusicParent?, isPlaying: Boolean) { + searchAdapter.setPlaying(parent ?: song, isPlaying) + } + + private fun handlePlaybackDecision(decision: PlaybackDecision?) { + if (decision == null) return + val directions = + when (decision) { + is PlaybackDecision.PlayFromArtist -> { + logD("Launching play from artist dialog for $decision") + SearchFragmentDirections.playFromArtist(decision.song.uid) + } + is PlaybackDecision.PlayFromGenre -> { + logD("Launching play from artist dialog for $decision") + SearchFragmentDirections.playFromGenre(decision.song.uid) + } + } + findNavController().navigateSafe(directions) + } + /** * Safely focus the keyboard on a particular [View]. *