music: simplify playlist decision events
Simplify the 4 stateflows controlling when playlist decision dialogs must be opened to just one enum. This is like the detail view, and makes the amount of observers I have to spin up much smaller. Eventually, most of even these observer calls will be collapsed into the menu itself.
This commit is contained in:
parent
07e9ca8ef6
commit
9b0e39919b
9 changed files with 229 additions and 80 deletions
|
@ -62,8 +62,6 @@ import org.oxycblt.auxio.util.unlikelyToBeNull
|
|||
* high-level navigation features.
|
||||
*
|
||||
* @author Alexander Capehart (OxygenCobalt)
|
||||
*
|
||||
* TODO: Break up the god navigation setup going on here
|
||||
*/
|
||||
@AndroidEntryPoint
|
||||
class MainFragment :
|
||||
|
|
|
@ -46,6 +46,7 @@ import org.oxycblt.auxio.music.Music
|
|||
import org.oxycblt.auxio.music.MusicMode
|
||||
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.music.info.Disc
|
||||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||
|
@ -124,6 +125,7 @@ class AlbumDetailFragment :
|
|||
collectImmediately(detailModel.albumList, ::updateList)
|
||||
collect(detailModel.toShow.flow, ::handleShow)
|
||||
collectImmediately(selectionModel.selected, ::updateSelection)
|
||||
collect(musicModel.playlistDecision.flow, ::handleDecision)
|
||||
collectImmediately(
|
||||
playbackModel.song, playbackModel.parent, playbackModel.isPlaying, ::updatePlayback)
|
||||
collect(playbackModel.artistPickerSong.flow, ::handlePlayFromArtist)
|
||||
|
@ -298,6 +300,36 @@ class AlbumDetailFragment :
|
|||
}
|
||||
}
|
||||
|
||||
private fun updateSelection(selected: List<Music>) {
|
||||
albumListAdapter.setSelected(selected.toSet())
|
||||
|
||||
val binding = requireBinding()
|
||||
if (selected.isNotEmpty()) {
|
||||
binding.detailSelectionToolbar.title = getString(R.string.fmt_selected, selected.size)
|
||||
binding.detailToolbar.setVisible(R.id.detail_selection_toolbar)
|
||||
} else {
|
||||
binding.detailToolbar.setVisible(R.id.detail_normal_toolbar)
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleDecision(decision: PlaylistDecision?) {
|
||||
when (decision) {
|
||||
is PlaylistDecision.Add ->{
|
||||
logD("Adding ${decision.songs.size} songs to a playlist")
|
||||
findNavController().navigateSafe(
|
||||
AlbumDetailFragmentDirections.addToPlaylist(
|
||||
decision.songs.map { it.uid }.toTypedArray())
|
||||
)
|
||||
musicModel.playlistDecision.consume()
|
||||
}
|
||||
|
||||
is PlaylistDecision.New, is PlaylistDecision.Rename, is PlaylistDecision.Delete ->
|
||||
error("Unexpected decision $decision")
|
||||
|
||||
null -> {}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updatePlayback(song: Song?, parent: MusicParent?, isPlaying: Boolean) {
|
||||
albumListAdapter.setPlaying(
|
||||
song.takeIf { parent == detailModel.currentAlbum.value }, isPlaying)
|
||||
|
@ -352,16 +384,4 @@ class AlbumDetailFragment :
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateSelection(selected: List<Music>) {
|
||||
albumListAdapter.setSelected(selected.toSet())
|
||||
|
||||
val binding = requireBinding()
|
||||
if (selected.isNotEmpty()) {
|
||||
binding.detailSelectionToolbar.title = getString(R.string.fmt_selected, selected.size)
|
||||
binding.detailToolbar.setVisible(R.id.detail_selection_toolbar)
|
||||
} else {
|
||||
binding.detailToolbar.setVisible(R.id.detail_normal_toolbar)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@ import org.oxycblt.auxio.music.Artist
|
|||
import org.oxycblt.auxio.music.Music
|
||||
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.PlaybackViewModel
|
||||
import org.oxycblt.auxio.util.collect
|
||||
|
@ -124,11 +125,12 @@ class ArtistDetailFragment :
|
|||
collectImmediately(detailModel.currentArtist, ::updateArtist)
|
||||
collectImmediately(detailModel.artistList, ::updateList)
|
||||
collect(detailModel.toShow.flow, ::handleShow)
|
||||
collectImmediately(selectionModel.selected, ::updateSelection)
|
||||
collect(musicModel.playlistDecision.flow, ::handleDecision)
|
||||
collectImmediately(
|
||||
playbackModel.song, playbackModel.parent, playbackModel.isPlaying, ::updatePlayback)
|
||||
collect(playbackModel.artistPickerSong.flow, ::handlePlayFromArtist)
|
||||
collect(playbackModel.genrePickerSong.flow, ::handlePlayFromGenre)
|
||||
collectImmediately(selectionModel.selected, ::updateSelection)
|
||||
}
|
||||
|
||||
override fun onDestroyBinding(binding: FragmentDetailBinding) {
|
||||
|
@ -308,6 +310,36 @@ class ArtistDetailFragment :
|
|||
}
|
||||
}
|
||||
|
||||
private fun updateSelection(selected: List<Music>) {
|
||||
artistListAdapter.setSelected(selected.toSet())
|
||||
|
||||
val binding = requireBinding()
|
||||
if (selected.isNotEmpty()) {
|
||||
binding.detailSelectionToolbar.title = getString(R.string.fmt_selected, selected.size)
|
||||
binding.detailToolbar.setVisible(R.id.detail_selection_toolbar)
|
||||
} else {
|
||||
binding.detailToolbar.setVisible(R.id.detail_normal_toolbar)
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleDecision(decision: PlaylistDecision?) {
|
||||
when (decision) {
|
||||
is PlaylistDecision.Add ->{
|
||||
logD("Adding ${decision.songs.size} songs to a playlist")
|
||||
findNavController().navigateSafe(
|
||||
ArtistDetailFragmentDirections.addToPlaylist(
|
||||
decision.songs.map { it.uid }.toTypedArray())
|
||||
)
|
||||
musicModel.playlistDecision.consume()
|
||||
}
|
||||
|
||||
is PlaylistDecision.New, is PlaylistDecision.Rename, is PlaylistDecision.Delete ->
|
||||
error("Unexpected decision $decision")
|
||||
|
||||
null -> {}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updatePlayback(song: Song?, parent: MusicParent?, isPlaying: Boolean) {
|
||||
val currentArtist = unlikelyToBeNull(detailModel.currentArtist.value)
|
||||
val playingItem =
|
||||
|
@ -334,16 +366,4 @@ class ArtistDetailFragment :
|
|||
logD("Launching play from genre dialog for $song")
|
||||
findNavController().navigateSafe(AlbumDetailFragmentDirections.playFromGenre(song.uid))
|
||||
}
|
||||
|
||||
private fun updateSelection(selected: List<Music>) {
|
||||
artistListAdapter.setSelected(selected.toSet())
|
||||
|
||||
val binding = requireBinding()
|
||||
if (selected.isNotEmpty()) {
|
||||
binding.detailSelectionToolbar.title = getString(R.string.fmt_selected, selected.size)
|
||||
binding.detailToolbar.setVisible(R.id.detail_selection_toolbar)
|
||||
} else {
|
||||
binding.detailToolbar.setVisible(R.id.detail_normal_toolbar)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@ import org.oxycblt.auxio.music.Genre
|
|||
import org.oxycblt.auxio.music.Music
|
||||
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.PlaybackViewModel
|
||||
import org.oxycblt.auxio.util.collect
|
||||
|
@ -122,11 +123,12 @@ class GenreDetailFragment :
|
|||
collectImmediately(detailModel.currentGenre, ::updatePlaylist)
|
||||
collectImmediately(detailModel.genreList, ::updateList)
|
||||
collect(detailModel.toShow.flow, ::handleShow)
|
||||
collectImmediately(selectionModel.selected, ::updateSelection)
|
||||
collect(musicModel.playlistDecision.flow, ::handleDecision)
|
||||
collectImmediately(
|
||||
playbackModel.song, playbackModel.parent, playbackModel.isPlaying, ::updatePlayback)
|
||||
collect(playbackModel.artistPickerSong.flow, ::handlePlayFromArtist)
|
||||
collect(playbackModel.genrePickerSong.flow, ::handlePlayFromGenre)
|
||||
collectImmediately(selectionModel.selected, ::updateSelection)
|
||||
}
|
||||
|
||||
override fun onDestroyBinding(binding: FragmentDetailBinding) {
|
||||
|
@ -295,6 +297,36 @@ class GenreDetailFragment :
|
|||
}
|
||||
}
|
||||
|
||||
private fun updateSelection(selected: List<Music>) {
|
||||
genreListAdapter.setSelected(selected.toSet())
|
||||
|
||||
val binding = requireBinding()
|
||||
if (selected.isNotEmpty()) {
|
||||
binding.detailSelectionToolbar.title = getString(R.string.fmt_selected, selected.size)
|
||||
binding.detailToolbar.setVisible(R.id.detail_selection_toolbar)
|
||||
} else {
|
||||
binding.detailToolbar.setVisible(R.id.detail_normal_toolbar)
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleDecision(decision: PlaylistDecision?) {
|
||||
when (decision) {
|
||||
is PlaylistDecision.Add ->{
|
||||
logD("Adding ${decision.songs.size} songs to a playlist")
|
||||
findNavController().navigateSafe(
|
||||
GenreDetailFragmentDirections.addToPlaylist(
|
||||
decision.songs.map { it.uid }.toTypedArray())
|
||||
)
|
||||
musicModel.playlistDecision.consume()
|
||||
}
|
||||
|
||||
is PlaylistDecision.New, is PlaylistDecision.Rename, is PlaylistDecision.Delete ->
|
||||
error("Unexpected decision $decision")
|
||||
|
||||
null -> {}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updatePlayback(song: Song?, parent: MusicParent?, isPlaying: Boolean) {
|
||||
val currentGenre = unlikelyToBeNull(detailModel.currentGenre.value)
|
||||
val playingItem =
|
||||
|
@ -321,16 +353,4 @@ class GenreDetailFragment :
|
|||
logD("Launching play from genre dialog for $song")
|
||||
findNavController().navigateSafe(AlbumDetailFragmentDirections.playFromGenre(song.uid))
|
||||
}
|
||||
|
||||
private fun updateSelection(selected: List<Music>) {
|
||||
genreListAdapter.setSelected(selected.toSet())
|
||||
|
||||
val binding = requireBinding()
|
||||
if (selected.isNotEmpty()) {
|
||||
binding.detailSelectionToolbar.title = getString(R.string.fmt_selected, selected.size)
|
||||
binding.detailToolbar.setVisible(R.id.detail_selection_toolbar)
|
||||
} else {
|
||||
binding.detailToolbar.setVisible(R.id.detail_normal_toolbar)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@ import org.oxycblt.auxio.music.Music
|
|||
import org.oxycblt.auxio.music.MusicParent
|
||||
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.PlaybackViewModel
|
||||
import org.oxycblt.auxio.util.collect
|
||||
|
@ -137,11 +138,12 @@ class PlaylistDetailFragment :
|
|||
collectImmediately(detailModel.playlistList, ::updateList)
|
||||
collectImmediately(detailModel.editedPlaylist, ::updateEditedList)
|
||||
collect(detailModel.toShow.flow, ::handleShow)
|
||||
collectImmediately(selectionModel.selected, ::updateSelection)
|
||||
collect(musicModel.playlistDecision.flow, ::handleDecision)
|
||||
collectImmediately(
|
||||
playbackModel.song, playbackModel.parent, playbackModel.isPlaying, ::updatePlayback)
|
||||
collect(playbackModel.artistPickerSong.flow, ::handlePlayFromArtist)
|
||||
collect(playbackModel.genrePickerSong.flow, ::handlePlayFromGenre)
|
||||
collectImmediately(selectionModel.selected, ::updateSelection)
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
|
@ -342,6 +344,38 @@ class PlaylistDetailFragment :
|
|||
}
|
||||
}
|
||||
|
||||
private fun updateSelection(selected: List<Music>) {
|
||||
playlistListAdapter.setSelected(selected.toSet())
|
||||
|
||||
val binding = requireBinding()
|
||||
if (selected.isNotEmpty()) {
|
||||
binding.detailSelectionToolbar.title = getString(R.string.fmt_selected, selected.size)
|
||||
}
|
||||
updateMultiToolbar()
|
||||
}
|
||||
|
||||
private fun handleDecision(decision: PlaylistDecision?) {
|
||||
if (decision == null) return
|
||||
when (decision) {
|
||||
is PlaylistDecision.Rename -> {
|
||||
logD("Renaming ${decision.playlist}")
|
||||
findNavController().navigateSafe(
|
||||
PlaylistDetailFragmentDirections.renamePlaylist(decision.playlist.uid)
|
||||
)
|
||||
}
|
||||
|
||||
is PlaylistDecision.Delete -> {
|
||||
logD("Deleting ${decision.playlist}")
|
||||
findNavController().navigateSafe(
|
||||
PlaylistDetailFragmentDirections.deletePlaylist(decision.playlist.uid)
|
||||
)
|
||||
}
|
||||
|
||||
is PlaylistDecision.Add, is PlaylistDecision.New -> error("Unexpected decision $decision")
|
||||
}
|
||||
musicModel.playlistDecision.consume()
|
||||
}
|
||||
|
||||
private fun updatePlayback(song: Song?, parent: MusicParent?, isPlaying: Boolean) {
|
||||
// Prefer songs that are playing from this playlist.
|
||||
playlistListAdapter.setPlaying(
|
||||
|
@ -359,17 +393,6 @@ class PlaylistDetailFragment :
|
|||
logD("Launching play from genre dialog for $song")
|
||||
findNavController().navigateSafe(AlbumDetailFragmentDirections.playFromGenre(song.uid))
|
||||
}
|
||||
|
||||
private fun updateSelection(selected: List<Music>) {
|
||||
playlistListAdapter.setSelected(selected.toSet())
|
||||
|
||||
val binding = requireBinding()
|
||||
if (selected.isNotEmpty()) {
|
||||
binding.detailSelectionToolbar.title = getString(R.string.fmt_selected, selected.size)
|
||||
}
|
||||
updateMultiToolbar()
|
||||
}
|
||||
|
||||
private fun updateMultiToolbar() {
|
||||
val id =
|
||||
when {
|
||||
|
|
|
@ -130,6 +130,7 @@ class SongDetailDialog : ViewBindingDialogFragment<DialogSongDetailBinding>() {
|
|||
if (show == null) return
|
||||
if (show is Show.SongDetails) {
|
||||
logD("Navigated to this song")
|
||||
detailModel.toShow.consume()
|
||||
} else {
|
||||
error("Unexpected show command $show")
|
||||
}
|
||||
|
|
|
@ -65,6 +65,7 @@ import org.oxycblt.auxio.music.MusicViewModel
|
|||
import org.oxycblt.auxio.music.NoAudioPermissionException
|
||||
import org.oxycblt.auxio.music.NoMusicException
|
||||
import org.oxycblt.auxio.music.PERMISSION_READ_AUDIO
|
||||
import org.oxycblt.auxio.music.PlaylistDecision
|
||||
import org.oxycblt.auxio.music.Song
|
||||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||
import org.oxycblt.auxio.util.collect
|
||||
|
@ -85,9 +86,9 @@ import org.oxycblt.auxio.util.unlikelyToBeNull
|
|||
@AndroidEntryPoint
|
||||
class HomeFragment :
|
||||
SelectionFragment<FragmentHomeBinding>(), AppBarLayout.OnOffsetChangedListener {
|
||||
override val playbackModel: PlaybackViewModel by activityViewModels()
|
||||
override val selectionModel: SelectionViewModel by activityViewModels()
|
||||
override val musicModel: MusicViewModel by activityViewModels()
|
||||
override val playbackModel: PlaybackViewModel by activityViewModels()
|
||||
private val homeModel: HomeViewModel by activityViewModels()
|
||||
private val detailModel: DetailViewModel by activityViewModels()
|
||||
private var storagePermissionLauncher: ActivityResultLauncher<String>? = null
|
||||
|
@ -171,9 +172,10 @@ class HomeFragment :
|
|||
collect(homeModel.recreateTabs.flow, ::handleRecreate)
|
||||
collectImmediately(homeModel.currentTabMode, ::updateCurrentTab)
|
||||
collectImmediately(homeModel.songsList, homeModel.isFastScrolling, ::updateFab)
|
||||
collectImmediately(musicModel.indexingState, ::updateIndexerState)
|
||||
collect(detailModel.toShow.flow, ::handleShow)
|
||||
collectImmediately(selectionModel.selected, ::updateSelection)
|
||||
collectImmediately(musicModel.indexingState, ::updateIndexerState)
|
||||
collect(musicModel.playlistDecision.flow, ::handleDecision)
|
||||
collect(detailModel.toShow.flow, ::handleShow)
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
|
@ -479,6 +481,39 @@ class HomeFragment :
|
|||
}
|
||||
}
|
||||
|
||||
private fun handleDecision(decision: PlaylistDecision?) {
|
||||
if (decision == null) return
|
||||
when (decision) {
|
||||
is PlaylistDecision.New -> {
|
||||
logD("Creating new playlist")
|
||||
findNavController().navigateSafe(
|
||||
HomeFragmentDirections.newPlaylist(decision.songs.map { it.uid }.toTypedArray()))
|
||||
}
|
||||
|
||||
is PlaylistDecision.Rename -> {
|
||||
logD("Renaming ${decision.playlist}")
|
||||
findNavController().navigateSafe(
|
||||
HomeFragmentDirections.renamePlaylist(decision.playlist.uid)
|
||||
)
|
||||
}
|
||||
|
||||
is PlaylistDecision.Delete -> {
|
||||
logD("Deleting ${decision.playlist}")
|
||||
findNavController().navigateSafe(
|
||||
HomeFragmentDirections.deletePlaylist(decision.playlist.uid)
|
||||
)
|
||||
}
|
||||
|
||||
is PlaylistDecision.Add -> {
|
||||
logD("Adding ${decision.songs.size} to a playlist")
|
||||
findNavController().navigateSafe(
|
||||
HomeFragmentDirections.addToPlaylist(decision.songs.map { it.uid }.toTypedArray())
|
||||
)
|
||||
}
|
||||
}
|
||||
musicModel.playlistDecision.consume()
|
||||
}
|
||||
|
||||
private fun updateFab(songs: List<Song>, isFastScrolling: Boolean) {
|
||||
val binding = requireBinding()
|
||||
// If there are no songs, it's likely that the library has not been loaded, so
|
||||
|
|
|
@ -52,23 +52,8 @@ constructor(
|
|||
val statistics: StateFlow<Statistics?>
|
||||
get() = _statistics
|
||||
|
||||
private val _newPlaylistSongs = MutableEvent<List<Song>>()
|
||||
/** Flag for opening a dialog to create a playlist of the given [Song]s. */
|
||||
val newPlaylistSongs: Event<List<Song>> = _newPlaylistSongs
|
||||
|
||||
private val _playlistToRename = MutableEvent<Playlist?>()
|
||||
/** Flag for opening a dialog to rename the given [Playlist]. */
|
||||
val playlistToRename: Event<Playlist?>
|
||||
get() = _playlistToRename
|
||||
|
||||
private val _playlistToDelete = MutableEvent<Playlist>()
|
||||
/** Flag for opening a dialog to confirm deletion of the given [Playlist]. */
|
||||
val playlistToDelete: Event<Playlist>
|
||||
get() = _playlistToDelete
|
||||
|
||||
private val _songsToAdd = MutableEvent<List<Song>>()
|
||||
/** Flag for opening a dialog to add the given [Song]s to a playlist. */
|
||||
val songsToAdd: Event<List<Song>> = _songsToAdd
|
||||
private val _playlistDecision = MutableEvent<PlaylistDecision>()
|
||||
val playlistDecision: Event<PlaylistDecision> get() = _playlistDecision
|
||||
|
||||
init {
|
||||
musicRepository.addUpdateListener(this)
|
||||
|
@ -121,7 +106,7 @@ constructor(
|
|||
viewModelScope.launch(Dispatchers.IO) { musicRepository.createPlaylist(name, songs) }
|
||||
} else {
|
||||
logD("Launching creation dialog for ${songs.size} songs")
|
||||
_newPlaylistSongs.put(songs)
|
||||
_playlistDecision.put(PlaylistDecision.New(songs))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -137,7 +122,7 @@ constructor(
|
|||
viewModelScope.launch(Dispatchers.IO) { musicRepository.renamePlaylist(playlist, name) }
|
||||
} else {
|
||||
logD("Launching rename dialog for $playlist")
|
||||
_playlistToRename.put(playlist)
|
||||
_playlistDecision.put(PlaylistDecision.Rename(playlist))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -154,7 +139,7 @@ constructor(
|
|||
viewModelScope.launch(Dispatchers.IO) { musicRepository.deletePlaylist(playlist) }
|
||||
} else {
|
||||
logD("Launching deletion dialog for $playlist")
|
||||
_playlistToDelete.put(playlist)
|
||||
_playlistDecision.put(PlaylistDecision.Delete(playlist))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -214,7 +199,7 @@ constructor(
|
|||
viewModelScope.launch(Dispatchers.IO) { musicRepository.addToPlaylist(songs, playlist) }
|
||||
} else {
|
||||
logD("Launching addition dialog for songs=${songs.size}")
|
||||
_songsToAdd.put(songs)
|
||||
_playlistDecision.put(PlaylistDecision.Add(songs))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -235,3 +220,10 @@ constructor(
|
|||
val durationMs: Long
|
||||
)
|
||||
}
|
||||
|
||||
sealed interface PlaylistDecision {
|
||||
data class New(val songs: List<Song>) : PlaylistDecision
|
||||
data class Rename(val playlist: Playlist) : PlaylistDecision
|
||||
data class Delete(val playlist: Playlist) : PlaylistDecision
|
||||
data class Add(val songs: List<Song>) : PlaylistDecision
|
||||
}
|
||||
|
|
|
@ -34,8 +34,10 @@ import com.google.android.material.transition.MaterialSharedAxis
|
|||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import org.oxycblt.auxio.R
|
||||
import org.oxycblt.auxio.databinding.FragmentSearchBinding
|
||||
import org.oxycblt.auxio.detail.ArtistDetailFragmentDirections
|
||||
import org.oxycblt.auxio.detail.DetailViewModel
|
||||
import org.oxycblt.auxio.detail.Show
|
||||
import org.oxycblt.auxio.home.HomeFragmentDirections
|
||||
import org.oxycblt.auxio.list.Divider
|
||||
import org.oxycblt.auxio.list.Header
|
||||
import org.oxycblt.auxio.list.Item
|
||||
|
@ -48,6 +50,7 @@ import org.oxycblt.auxio.music.Music
|
|||
import org.oxycblt.auxio.music.MusicParent
|
||||
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.PlaybackViewModel
|
||||
import org.oxycblt.auxio.util.collect
|
||||
|
@ -136,10 +139,11 @@ class SearchFragment : ListFragment<Music, FragmentSearchBinding>() {
|
|||
// --- VIEWMODEL SETUP ---
|
||||
|
||||
collectImmediately(searchModel.searchResults, ::updateSearchResults)
|
||||
collectImmediately(selectionModel.selected, ::updateSelection)
|
||||
collect(musicModel.playlistDecision.flow, ::handleDecision)
|
||||
collectImmediately(
|
||||
playbackModel.song, playbackModel.parent, playbackModel.isPlaying, ::updatePlayback)
|
||||
collect(detailModel.toShow.flow, ::handleShow)
|
||||
collectImmediately(selectionModel.selected, ::updateSelection)
|
||||
}
|
||||
|
||||
override fun onDestroyBinding(binding: FragmentSearchBinding) {
|
||||
|
@ -200,9 +204,7 @@ class SearchFragment : ListFragment<Music, FragmentSearchBinding>() {
|
|||
}
|
||||
}
|
||||
|
||||
private fun updatePlayback(song: Song?, parent: MusicParent?, isPlaying: Boolean) {
|
||||
searchAdapter.setPlaying(parent ?: song, isPlaying)
|
||||
}
|
||||
|
||||
|
||||
private fun handleShow(show: Show?) {
|
||||
when (show) {
|
||||
|
@ -257,6 +259,44 @@ class SearchFragment : ListFragment<Music, FragmentSearchBinding>() {
|
|||
hideKeyboard()
|
||||
}
|
||||
|
||||
|
||||
private fun handleDecision(decision: PlaylistDecision?) {
|
||||
if (decision == null) return
|
||||
when (decision) {
|
||||
is PlaylistDecision.New -> {
|
||||
logD("Creating new playlist")
|
||||
findNavController().navigateSafe(
|
||||
HomeFragmentDirections.newPlaylist(decision.songs.map { it.uid }.toTypedArray()))
|
||||
}
|
||||
|
||||
is PlaylistDecision.Rename -> {
|
||||
logD("Renaming ${decision.playlist}")
|
||||
findNavController().navigateSafe(
|
||||
HomeFragmentDirections.renamePlaylist(decision.playlist.uid)
|
||||
)
|
||||
}
|
||||
|
||||
is PlaylistDecision.Delete -> {
|
||||
logD("Deleting ${decision.playlist}")
|
||||
findNavController().navigateSafe(
|
||||
SearchFragmentDirections.deletePlaylist(decision.playlist.uid)
|
||||
)
|
||||
}
|
||||
|
||||
is PlaylistDecision.Add -> {
|
||||
logD("Adding ${decision.songs.size} to a playlist")
|
||||
findNavController().navigateSafe(
|
||||
HomeFragmentDirections.addToPlaylist(decision.songs.map { it.uid }.toTypedArray())
|
||||
)
|
||||
}
|
||||
}
|
||||
musicModel.playlistDecision.consume()
|
||||
}
|
||||
|
||||
private fun updatePlayback(song: Song?, parent: MusicParent?, isPlaying: Boolean) {
|
||||
searchAdapter.setPlaying(parent ?: song, isPlaying)
|
||||
}
|
||||
|
||||
private fun updateSelection(selected: List<Music>) {
|
||||
searchAdapter.setSelected(selected.toSet())
|
||||
val binding = requireBinding()
|
||||
|
|
Loading…
Reference in a new issue