all: standardize nav consume usage
Standardize navigation command consumption to only occur when a navigation route has *definitively* ended. If more commands could come, observe them. Otherwise, consume immediately.
This commit is contained in:
parent
e8289dcda0
commit
14107c9444
24 changed files with 134 additions and 168 deletions
|
@ -57,8 +57,7 @@ import org.oxycblt.auxio.util.systemBarInsetsCompat
|
||||||
import org.oxycblt.auxio.util.unlikelyToBeNull
|
import org.oxycblt.auxio.util.unlikelyToBeNull
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A wrapper around the home fragment that shows the playback fragment and controls the more
|
* A wrapper around the home fragment that shows the playback fragment and high-level navigation.
|
||||||
* high-level navigation features.
|
|
||||||
*
|
*
|
||||||
* @author Alexander Capehart (OxygenCobalt)
|
* @author Alexander Capehart (OxygenCobalt)
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -73,7 +73,7 @@ class AlbumDetailFragment :
|
||||||
ListFragment<Song, FragmentDetailBinding>(),
|
ListFragment<Song, FragmentDetailBinding>(),
|
||||||
AlbumDetailHeaderAdapter.Listener,
|
AlbumDetailHeaderAdapter.Listener,
|
||||||
DetailListAdapter.Listener<Song> {
|
DetailListAdapter.Listener<Song> {
|
||||||
override val detailModel: DetailViewModel by activityViewModels()
|
private val detailModel: DetailViewModel by activityViewModels()
|
||||||
private val menuModel: MenuViewModel by activityViewModels()
|
private val menuModel: MenuViewModel by activityViewModels()
|
||||||
override val selectionModel: SelectionViewModel by activityViewModels()
|
override val selectionModel: SelectionViewModel by activityViewModels()
|
||||||
override val musicModel: MusicViewModel by activityViewModels()
|
override val musicModel: MusicViewModel by activityViewModels()
|
||||||
|
@ -317,7 +317,6 @@ class AlbumDetailFragment :
|
||||||
is PendingMenu.ForPlaylist -> error("Unexpected menu $pendingMenu")
|
is PendingMenu.ForPlaylist -> error("Unexpected menu $pendingMenu")
|
||||||
}
|
}
|
||||||
findNavController().navigateSafe(directions)
|
findNavController().navigateSafe(directions)
|
||||||
menuModel.pendingMenu.consume()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateSelection(selected: List<Music>) {
|
private fun updateSelection(selected: List<Music>) {
|
||||||
|
@ -333,20 +332,19 @@ class AlbumDetailFragment :
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleDecision(decision: PlaylistDecision?) {
|
private fun handleDecision(decision: PlaylistDecision?) {
|
||||||
|
if (decision == null) return
|
||||||
|
val directions =
|
||||||
when (decision) {
|
when (decision) {
|
||||||
is PlaylistDecision.Add -> {
|
is PlaylistDecision.Add -> {
|
||||||
logD("Adding ${decision.songs.size} songs to a playlist")
|
logD("Adding ${decision.songs.size} songs to a playlist")
|
||||||
findNavController()
|
|
||||||
.navigateSafe(
|
|
||||||
AlbumDetailFragmentDirections.addToPlaylist(
|
AlbumDetailFragmentDirections.addToPlaylist(
|
||||||
decision.songs.map { it.uid }.toTypedArray()))
|
decision.songs.map { it.uid }.toTypedArray())
|
||||||
musicModel.playlistDecision.consume()
|
|
||||||
}
|
}
|
||||||
is PlaylistDecision.New,
|
is PlaylistDecision.New,
|
||||||
is PlaylistDecision.Rename,
|
is PlaylistDecision.Rename,
|
||||||
is PlaylistDecision.Delete -> error("Unexpected decision $decision")
|
is PlaylistDecision.Delete -> error("Unexpected decision $decision")
|
||||||
null -> {}
|
|
||||||
}
|
}
|
||||||
|
findNavController().navigateSafe(directions)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updatePlayback(song: Song?, parent: MusicParent?, isPlaying: Boolean) {
|
private fun updatePlayback(song: Song?, parent: MusicParent?, isPlaying: Boolean) {
|
||||||
|
|
|
@ -71,7 +71,7 @@ class ArtistDetailFragment :
|
||||||
ListFragment<Music, FragmentDetailBinding>(),
|
ListFragment<Music, FragmentDetailBinding>(),
|
||||||
DetailHeaderAdapter.Listener,
|
DetailHeaderAdapter.Listener,
|
||||||
DetailListAdapter.Listener<Music> {
|
DetailListAdapter.Listener<Music> {
|
||||||
override val detailModel: DetailViewModel by activityViewModels()
|
private val detailModel: DetailViewModel by activityViewModels()
|
||||||
private val menuModel: MenuViewModel by activityViewModels()
|
private val menuModel: MenuViewModel by activityViewModels()
|
||||||
override val selectionModel: SelectionViewModel by activityViewModels()
|
override val selectionModel: SelectionViewModel by activityViewModels()
|
||||||
override val musicModel: MusicViewModel by activityViewModels()
|
override val musicModel: MusicViewModel by activityViewModels()
|
||||||
|
@ -329,7 +329,6 @@ class ArtistDetailFragment :
|
||||||
is PendingMenu.ForPlaylist -> error("Unexpected menu $pendingMenu")
|
is PendingMenu.ForPlaylist -> error("Unexpected menu $pendingMenu")
|
||||||
}
|
}
|
||||||
findNavController().navigateSafe(directions)
|
findNavController().navigateSafe(directions)
|
||||||
menuModel.pendingMenu.consume()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateSelection(selected: List<Music>) {
|
private fun updateSelection(selected: List<Music>) {
|
||||||
|
@ -345,20 +344,19 @@ class ArtistDetailFragment :
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleDecision(decision: PlaylistDecision?) {
|
private fun handleDecision(decision: PlaylistDecision?) {
|
||||||
|
if (decision == null) return
|
||||||
|
val directions =
|
||||||
when (decision) {
|
when (decision) {
|
||||||
is PlaylistDecision.Add -> {
|
is PlaylistDecision.Add -> {
|
||||||
logD("Adding ${decision.songs.size} songs to a playlist")
|
logD("Adding ${decision.songs.size} songs to a playlist")
|
||||||
findNavController()
|
|
||||||
.navigateSafe(
|
|
||||||
ArtistDetailFragmentDirections.addToPlaylist(
|
ArtistDetailFragmentDirections.addToPlaylist(
|
||||||
decision.songs.map { it.uid }.toTypedArray()))
|
decision.songs.map { it.uid }.toTypedArray())
|
||||||
musicModel.playlistDecision.consume()
|
|
||||||
}
|
}
|
||||||
is PlaylistDecision.New,
|
is PlaylistDecision.New,
|
||||||
is PlaylistDecision.Rename,
|
is PlaylistDecision.Rename,
|
||||||
is PlaylistDecision.Delete -> error("Unexpected decision $decision")
|
is PlaylistDecision.Delete -> error("Unexpected decision $decision")
|
||||||
null -> {}
|
|
||||||
}
|
}
|
||||||
|
findNavController().navigateSafe(directions)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updatePlayback(song: Song?, parent: MusicParent?, isPlaying: Boolean) {
|
private fun updatePlayback(song: Song?, parent: MusicParent?, isPlaying: Boolean) {
|
||||||
|
|
|
@ -71,7 +71,7 @@ class GenreDetailFragment :
|
||||||
ListFragment<Music, FragmentDetailBinding>(),
|
ListFragment<Music, FragmentDetailBinding>(),
|
||||||
DetailHeaderAdapter.Listener,
|
DetailHeaderAdapter.Listener,
|
||||||
DetailListAdapter.Listener<Music> {
|
DetailListAdapter.Listener<Music> {
|
||||||
override val detailModel: DetailViewModel by activityViewModels()
|
private val detailModel: DetailViewModel by activityViewModels()
|
||||||
private val menuModel: MenuViewModel by activityViewModels()
|
private val menuModel: MenuViewModel by activityViewModels()
|
||||||
override val selectionModel: SelectionViewModel by activityViewModels()
|
override val selectionModel: SelectionViewModel by activityViewModels()
|
||||||
override val musicModel: MusicViewModel by activityViewModels()
|
override val musicModel: MusicViewModel by activityViewModels()
|
||||||
|
@ -317,7 +317,6 @@ class GenreDetailFragment :
|
||||||
is PendingMenu.ForPlaylist -> error("Unexpected menu $pendingMenu")
|
is PendingMenu.ForPlaylist -> error("Unexpected menu $pendingMenu")
|
||||||
}
|
}
|
||||||
findNavController().navigateSafe(directions)
|
findNavController().navigateSafe(directions)
|
||||||
menuModel.pendingMenu.consume()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateSelection(selected: List<Music>) {
|
private fun updateSelection(selected: List<Music>) {
|
||||||
|
@ -333,20 +332,19 @@ class GenreDetailFragment :
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleDecision(decision: PlaylistDecision?) {
|
private fun handleDecision(decision: PlaylistDecision?) {
|
||||||
|
if (decision == null) return
|
||||||
|
val directions =
|
||||||
when (decision) {
|
when (decision) {
|
||||||
is PlaylistDecision.Add -> {
|
is PlaylistDecision.Add -> {
|
||||||
logD("Adding ${decision.songs.size} songs to a playlist")
|
logD("Adding ${decision.songs.size} songs to a playlist")
|
||||||
findNavController()
|
ArtistDetailFragmentDirections.addToPlaylist(
|
||||||
.navigateSafe(
|
decision.songs.map { it.uid }.toTypedArray())
|
||||||
GenreDetailFragmentDirections.addToPlaylist(
|
|
||||||
decision.songs.map { it.uid }.toTypedArray()))
|
|
||||||
musicModel.playlistDecision.consume()
|
|
||||||
}
|
}
|
||||||
is PlaylistDecision.New,
|
is PlaylistDecision.New,
|
||||||
is PlaylistDecision.Rename,
|
is PlaylistDecision.Rename,
|
||||||
is PlaylistDecision.Delete -> error("Unexpected decision $decision")
|
is PlaylistDecision.Delete -> error("Unexpected decision $decision")
|
||||||
null -> {}
|
|
||||||
}
|
}
|
||||||
|
findNavController().navigateSafe(directions)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updatePlayback(song: Song?, parent: MusicParent?, isPlaying: Boolean) {
|
private fun updatePlayback(song: Song?, parent: MusicParent?, isPlaying: Boolean) {
|
||||||
|
|
|
@ -74,7 +74,7 @@ class PlaylistDetailFragment :
|
||||||
DetailHeaderAdapter.Listener,
|
DetailHeaderAdapter.Listener,
|
||||||
PlaylistDetailListAdapter.Listener,
|
PlaylistDetailListAdapter.Listener,
|
||||||
NavController.OnDestinationChangedListener {
|
NavController.OnDestinationChangedListener {
|
||||||
override val detailModel: DetailViewModel by activityViewModels()
|
private val detailModel: DetailViewModel by activityViewModels()
|
||||||
private val menuModel: MenuViewModel by activityViewModels()
|
private val menuModel: MenuViewModel by activityViewModels()
|
||||||
override val selectionModel: SelectionViewModel by activityViewModels()
|
override val selectionModel: SelectionViewModel by activityViewModels()
|
||||||
override val musicModel: MusicViewModel by activityViewModels()
|
override val musicModel: MusicViewModel by activityViewModels()
|
||||||
|
@ -362,7 +362,6 @@ class PlaylistDetailFragment :
|
||||||
is PendingMenu.ForPlaylist -> error("Unexpected menu $pendingMenu")
|
is PendingMenu.ForPlaylist -> error("Unexpected menu $pendingMenu")
|
||||||
}
|
}
|
||||||
findNavController().navigateSafe(directions)
|
findNavController().navigateSafe(directions)
|
||||||
menuModel.pendingMenu.consume()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateSelection(selected: List<Music>) {
|
private fun updateSelection(selected: List<Music>) {
|
||||||
|
@ -377,23 +376,20 @@ class PlaylistDetailFragment :
|
||||||
|
|
||||||
private fun handleDecision(decision: PlaylistDecision?) {
|
private fun handleDecision(decision: PlaylistDecision?) {
|
||||||
if (decision == null) return
|
if (decision == null) return
|
||||||
|
val directions =
|
||||||
when (decision) {
|
when (decision) {
|
||||||
is PlaylistDecision.Rename -> {
|
is PlaylistDecision.Rename -> {
|
||||||
logD("Renaming ${decision.playlist}")
|
logD("Renaming ${decision.playlist}")
|
||||||
findNavController()
|
PlaylistDetailFragmentDirections.renamePlaylist(decision.playlist.uid)
|
||||||
.navigateSafe(
|
|
||||||
PlaylistDetailFragmentDirections.renamePlaylist(decision.playlist.uid))
|
|
||||||
}
|
}
|
||||||
is PlaylistDecision.Delete -> {
|
is PlaylistDecision.Delete -> {
|
||||||
logD("Deleting ${decision.playlist}")
|
logD("Deleting ${decision.playlist}")
|
||||||
findNavController()
|
PlaylistDetailFragmentDirections.deletePlaylist(decision.playlist.uid)
|
||||||
.navigateSafe(
|
|
||||||
PlaylistDetailFragmentDirections.deletePlaylist(decision.playlist.uid))
|
|
||||||
}
|
}
|
||||||
is PlaylistDecision.Add,
|
is PlaylistDecision.Add,
|
||||||
is PlaylistDecision.New -> error("Unexpected decision $decision")
|
is PlaylistDecision.New -> error("Unexpected decision $decision")
|
||||||
}
|
}
|
||||||
musicModel.playlistDecision.consume()
|
findNavController().navigateSafe(directions)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updatePlayback(song: Song?, parent: MusicParent?, isPlaying: Boolean) {
|
private fun updatePlayback(song: Song?, parent: MusicParent?, isPlaying: Boolean) {
|
||||||
|
|
|
@ -69,8 +69,8 @@ class SongDetailDialog : ViewBindingMaterialDialogFragment<DialogSongDetailBindi
|
||||||
binding.detailProperties.adapter = detailAdapter
|
binding.detailProperties.adapter = detailAdapter
|
||||||
// DetailViewModel handles most initialization from the navigation argument.
|
// DetailViewModel handles most initialization from the navigation argument.
|
||||||
detailModel.setSong(args.songUid)
|
detailModel.setSong(args.songUid)
|
||||||
|
detailModel.toShow.consume()
|
||||||
collectImmediately(detailModel.currentSong, detailModel.songAudioProperties, ::updateSong)
|
collectImmediately(detailModel.currentSong, detailModel.songAudioProperties, ::updateSong)
|
||||||
collectImmediately(detailModel.toShow.flow, ::handleShow)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateSong(song: Song?, info: AudioProperties?) {
|
private fun updateSong(song: Song?, info: AudioProperties?) {
|
||||||
|
@ -126,16 +126,6 @@ class SongDetailDialog : ViewBindingMaterialDialogFragment<DialogSongDetailBindi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleShow(show: Show?) {
|
|
||||||
if (show == null) return
|
|
||||||
if (show is Show.SongDetails) {
|
|
||||||
logD("Navigated to this song")
|
|
||||||
detailModel.toShow.consume()
|
|
||||||
} else {
|
|
||||||
error("Unexpected show command $show")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun <T : Music> T.zipName(context: Context): String {
|
private fun <T : Music> T.zipName(context: Context): String {
|
||||||
val name = name
|
val name = name
|
||||||
return if (name is Name.Known && name.sort != null) {
|
return if (name is Name.Known && name.sort != null) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2023 Auxio Project
|
* Copyright (c) 2023 Auxio Project
|
||||||
* NavigationPickerViewModel.kt is part of Auxio.
|
* DetailPickerViewModel.kt is part of Auxio.
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -49,6 +49,11 @@ class NavigationPickerViewModel @Inject constructor(private val musicRepository:
|
||||||
musicRepository.addUpdateListener(this)
|
musicRepository.addUpdateListener(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onCleared() {
|
||||||
|
super.onCleared()
|
||||||
|
musicRepository.removeUpdateListener(this)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onMusicChanges(changes: MusicRepository.Changes) {
|
override fun onMusicChanges(changes: MusicRepository.Changes) {
|
||||||
if (!changes.deviceLibrary) return
|
if (!changes.deviceLibrary) return
|
||||||
val deviceLibrary = musicRepository.deviceLibrary ?: return
|
val deviceLibrary = musicRepository.deviceLibrary ?: return
|
||||||
|
@ -57,11 +62,6 @@ class NavigationPickerViewModel @Inject constructor(private val musicRepository:
|
||||||
logD("Updated artist choices: ${_artistChoices.value}")
|
logD("Updated artist choices: ${_artistChoices.value}")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCleared() {
|
|
||||||
super.onCleared()
|
|
||||||
musicRepository.removeUpdateListener(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the [Music.UID] of the item to show artist choices for.
|
* Set the [Music.UID] of the item to show artist choices for.
|
||||||
*
|
*
|
|
@ -35,6 +35,7 @@ import org.oxycblt.auxio.list.adapter.UpdateInstructions
|
||||||
import org.oxycblt.auxio.music.Artist
|
import org.oxycblt.auxio.music.Artist
|
||||||
import org.oxycblt.auxio.ui.ViewBindingMaterialDialogFragment
|
import org.oxycblt.auxio.ui.ViewBindingMaterialDialogFragment
|
||||||
import org.oxycblt.auxio.util.collectImmediately
|
import org.oxycblt.auxio.util.collectImmediately
|
||||||
|
import org.oxycblt.auxio.util.logD
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A picker [ViewBindingMaterialDialogFragment] intended for when the [Artist] to show is ambiguous.
|
* A picker [ViewBindingMaterialDialogFragment] intended for when the [Artist] to show is ambiguous.
|
||||||
|
@ -66,14 +67,9 @@ class ShowArtistDialog :
|
||||||
adapter = choiceAdapter
|
adapter = choiceAdapter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
detailModel.toShow.consume()
|
||||||
pickerModel.setArtistChoiceUid(args.itemUid)
|
pickerModel.setArtistChoiceUid(args.itemUid)
|
||||||
collectImmediately(pickerModel.artistChoices) {
|
collectImmediately(pickerModel.artistChoices, ::handleChoices)
|
||||||
if (it != null) {
|
|
||||||
choiceAdapter.update(it.choices, UpdateInstructions.Replace(0))
|
|
||||||
} else {
|
|
||||||
findNavController().navigateUp()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyBinding(binding: DialogMusicChoicesBinding) {
|
override fun onDestroyBinding(binding: DialogMusicChoicesBinding) {
|
||||||
|
@ -82,8 +78,17 @@ class ShowArtistDialog :
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onClick(item: Artist, viewHolder: RecyclerView.ViewHolder) {
|
override fun onClick(item: Artist, viewHolder: RecyclerView.ViewHolder) {
|
||||||
|
findNavController().navigateUp()
|
||||||
// User made a choice, navigate to the artist.
|
// User made a choice, navigate to the artist.
|
||||||
detailModel.showArtist(item)
|
detailModel.showArtist(item)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleChoices(choices: ArtistShowChoices?) {
|
||||||
|
if (choices == null) {
|
||||||
|
logD("No choices to show, navigating away")
|
||||||
findNavController().navigateUp()
|
findNavController().navigateUp()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
choiceAdapter.update(choices.choices, UpdateInstructions.Diff)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -492,33 +492,27 @@ class HomeFragment :
|
||||||
|
|
||||||
private fun handleDecision(decision: PlaylistDecision?) {
|
private fun handleDecision(decision: PlaylistDecision?) {
|
||||||
if (decision == null) return
|
if (decision == null) return
|
||||||
|
val directions =
|
||||||
when (decision) {
|
when (decision) {
|
||||||
is PlaylistDecision.New -> {
|
is PlaylistDecision.New -> {
|
||||||
logD("Creating new playlist")
|
logD("Creating new playlist")
|
||||||
findNavController()
|
HomeFragmentDirections.newPlaylist(decision.songs.map { it.uid }.toTypedArray())
|
||||||
.navigateSafe(
|
|
||||||
HomeFragmentDirections.newPlaylist(
|
|
||||||
decision.songs.map { it.uid }.toTypedArray()))
|
|
||||||
}
|
}
|
||||||
is PlaylistDecision.Rename -> {
|
is PlaylistDecision.Rename -> {
|
||||||
logD("Renaming ${decision.playlist}")
|
logD("Renaming ${decision.playlist}")
|
||||||
findNavController()
|
HomeFragmentDirections.renamePlaylist(decision.playlist.uid)
|
||||||
.navigateSafe(HomeFragmentDirections.renamePlaylist(decision.playlist.uid))
|
|
||||||
}
|
}
|
||||||
is PlaylistDecision.Delete -> {
|
is PlaylistDecision.Delete -> {
|
||||||
logD("Deleting ${decision.playlist}")
|
logD("Deleting ${decision.playlist}")
|
||||||
findNavController()
|
HomeFragmentDirections.deletePlaylist(decision.playlist.uid)
|
||||||
.navigateSafe(HomeFragmentDirections.deletePlaylist(decision.playlist.uid))
|
|
||||||
}
|
}
|
||||||
is PlaylistDecision.Add -> {
|
is PlaylistDecision.Add -> {
|
||||||
logD("Adding ${decision.songs.size} to a playlist")
|
logD("Adding ${decision.songs.size} to a playlist")
|
||||||
findNavController()
|
|
||||||
.navigateSafe(
|
|
||||||
HomeFragmentDirections.addToPlaylist(
|
HomeFragmentDirections.addToPlaylist(
|
||||||
decision.songs.map { it.uid }.toTypedArray()))
|
decision.songs.map { it.uid }.toTypedArray())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
musicModel.playlistDecision.consume()
|
findNavController().navigateSafe(directions)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateFab(songs: List<Song>, isFastScrolling: Boolean) {
|
private fun updateFab(songs: List<Song>, isFastScrolling: Boolean) {
|
||||||
|
@ -606,7 +600,6 @@ class HomeFragment :
|
||||||
pendingMenu.menuRes, pendingMenu.music.uid)
|
pendingMenu.menuRes, pendingMenu.music.uid)
|
||||||
}
|
}
|
||||||
findNavController().navigateSafe(directions)
|
findNavController().navigateSafe(directions)
|
||||||
menuModel.pendingMenu.consume()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateSelection(selected: List<Music>) {
|
private fun updateSelection(selected: List<Music>) {
|
||||||
|
|
|
@ -60,7 +60,7 @@ class AlbumListFragment :
|
||||||
FastScrollRecyclerView.Listener,
|
FastScrollRecyclerView.Listener,
|
||||||
FastScrollRecyclerView.PopupProvider {
|
FastScrollRecyclerView.PopupProvider {
|
||||||
private val homeModel: HomeViewModel by activityViewModels()
|
private val homeModel: HomeViewModel by activityViewModels()
|
||||||
override val detailModel: DetailViewModel by activityViewModels()
|
private val detailModel: DetailViewModel by activityViewModels()
|
||||||
private val menuModel: MenuViewModel by activityViewModels()
|
private val menuModel: MenuViewModel by activityViewModels()
|
||||||
override val selectionModel: SelectionViewModel by activityViewModels()
|
override val selectionModel: SelectionViewModel by activityViewModels()
|
||||||
override val musicModel: MusicViewModel by activityViewModels()
|
override val musicModel: MusicViewModel by activityViewModels()
|
||||||
|
|
|
@ -58,7 +58,7 @@ class ArtistListFragment :
|
||||||
FastScrollRecyclerView.PopupProvider,
|
FastScrollRecyclerView.PopupProvider,
|
||||||
FastScrollRecyclerView.Listener {
|
FastScrollRecyclerView.Listener {
|
||||||
private val homeModel: HomeViewModel by activityViewModels()
|
private val homeModel: HomeViewModel by activityViewModels()
|
||||||
override val detailModel: DetailViewModel by activityViewModels()
|
private val detailModel: DetailViewModel by activityViewModels()
|
||||||
private val menuModel: MenuViewModel by activityViewModels()
|
private val menuModel: MenuViewModel by activityViewModels()
|
||||||
override val selectionModel: SelectionViewModel by activityViewModels()
|
override val selectionModel: SelectionViewModel by activityViewModels()
|
||||||
override val musicModel: MusicViewModel by activityViewModels()
|
override val musicModel: MusicViewModel by activityViewModels()
|
||||||
|
|
|
@ -57,7 +57,7 @@ class GenreListFragment :
|
||||||
FastScrollRecyclerView.PopupProvider,
|
FastScrollRecyclerView.PopupProvider,
|
||||||
FastScrollRecyclerView.Listener {
|
FastScrollRecyclerView.Listener {
|
||||||
private val homeModel: HomeViewModel by activityViewModels()
|
private val homeModel: HomeViewModel by activityViewModels()
|
||||||
override val detailModel: DetailViewModel by activityViewModels()
|
private val detailModel: DetailViewModel by activityViewModels()
|
||||||
private val menuModel: MenuViewModel by activityViewModels()
|
private val menuModel: MenuViewModel by activityViewModels()
|
||||||
override val selectionModel: SelectionViewModel by activityViewModels()
|
override val selectionModel: SelectionViewModel by activityViewModels()
|
||||||
override val musicModel: MusicViewModel by activityViewModels()
|
override val musicModel: MusicViewModel by activityViewModels()
|
||||||
|
|
|
@ -55,7 +55,7 @@ class PlaylistListFragment :
|
||||||
FastScrollRecyclerView.PopupProvider,
|
FastScrollRecyclerView.PopupProvider,
|
||||||
FastScrollRecyclerView.Listener {
|
FastScrollRecyclerView.Listener {
|
||||||
private val homeModel: HomeViewModel by activityViewModels()
|
private val homeModel: HomeViewModel by activityViewModels()
|
||||||
override val detailModel: DetailViewModel by activityViewModels()
|
private val detailModel: DetailViewModel by activityViewModels()
|
||||||
private val menuModel: MenuViewModel by activityViewModels()
|
private val menuModel: MenuViewModel by activityViewModels()
|
||||||
override val selectionModel: SelectionViewModel by activityViewModels()
|
override val selectionModel: SelectionViewModel by activityViewModels()
|
||||||
override val musicModel: MusicViewModel by activityViewModels()
|
override val musicModel: MusicViewModel by activityViewModels()
|
||||||
|
|
|
@ -28,7 +28,6 @@ import dagger.hilt.android.AndroidEntryPoint
|
||||||
import java.util.Formatter
|
import java.util.Formatter
|
||||||
import org.oxycblt.auxio.R
|
import org.oxycblt.auxio.R
|
||||||
import org.oxycblt.auxio.databinding.FragmentHomeListBinding
|
import org.oxycblt.auxio.databinding.FragmentHomeListBinding
|
||||||
import org.oxycblt.auxio.detail.DetailViewModel
|
|
||||||
import org.oxycblt.auxio.home.HomeViewModel
|
import org.oxycblt.auxio.home.HomeViewModel
|
||||||
import org.oxycblt.auxio.home.fastscroll.FastScrollRecyclerView
|
import org.oxycblt.auxio.home.fastscroll.FastScrollRecyclerView
|
||||||
import org.oxycblt.auxio.list.ListFragment
|
import org.oxycblt.auxio.list.ListFragment
|
||||||
|
@ -59,7 +58,6 @@ class SongListFragment :
|
||||||
FastScrollRecyclerView.PopupProvider,
|
FastScrollRecyclerView.PopupProvider,
|
||||||
FastScrollRecyclerView.Listener {
|
FastScrollRecyclerView.Listener {
|
||||||
private val homeModel: HomeViewModel by activityViewModels()
|
private val homeModel: HomeViewModel by activityViewModels()
|
||||||
override val detailModel: DetailViewModel by activityViewModels()
|
|
||||||
private val menuModel: MenuViewModel by activityViewModels()
|
private val menuModel: MenuViewModel by activityViewModels()
|
||||||
override val selectionModel: SelectionViewModel by activityViewModels()
|
override val selectionModel: SelectionViewModel by activityViewModels()
|
||||||
override val musicModel: MusicViewModel by activityViewModels()
|
override val musicModel: MusicViewModel by activityViewModels()
|
||||||
|
|
|
@ -24,7 +24,6 @@ import androidx.appcompat.widget.PopupMenu
|
||||||
import androidx.core.view.MenuCompat
|
import androidx.core.view.MenuCompat
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import androidx.viewbinding.ViewBinding
|
import androidx.viewbinding.ViewBinding
|
||||||
import org.oxycblt.auxio.detail.DetailViewModel
|
|
||||||
import org.oxycblt.auxio.list.selection.SelectionFragment
|
import org.oxycblt.auxio.list.selection.SelectionFragment
|
||||||
import org.oxycblt.auxio.music.Music
|
import org.oxycblt.auxio.music.Music
|
||||||
import org.oxycblt.auxio.util.logD
|
import org.oxycblt.auxio.util.logD
|
||||||
|
@ -36,7 +35,6 @@ import org.oxycblt.auxio.util.logD
|
||||||
*/
|
*/
|
||||||
abstract class ListFragment<in T : Music, VB : ViewBinding> :
|
abstract class ListFragment<in T : Music, VB : ViewBinding> :
|
||||||
SelectionFragment<VB>(), SelectableListListener<T> {
|
SelectionFragment<VB>(), SelectableListListener<T> {
|
||||||
protected abstract val detailModel: DetailViewModel
|
|
||||||
private var currentMenu: PopupMenu? = null
|
private var currentMenu: PopupMenu? = null
|
||||||
|
|
||||||
override fun onDestroyBinding(binding: VB) {
|
override fun onDestroyBinding(binding: VB) {
|
||||||
|
|
|
@ -66,6 +66,7 @@ abstract class MenuDialogFragment<T : Music> :
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- VIEWMODEL SETUP ---
|
// --- VIEWMODEL SETUP ---
|
||||||
|
menuModel.pendingMenu.consume()
|
||||||
menuModel.setCurrentMenu(uid)
|
menuModel.setCurrentMenu(uid)
|
||||||
collectImmediately(menuModel.currentMusic, this::updateMusic)
|
collectImmediately(menuModel.currentMusic, this::updateMusic)
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,6 +72,7 @@ class AddToPlaylistDialog :
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- VIEWMODEL SETUP ---
|
// --- VIEWMODEL SETUP ---
|
||||||
|
musicModel.playlistDecision.consume()
|
||||||
pickerModel.setSongsToAdd(args.songUids)
|
pickerModel.setSongsToAdd(args.songUids)
|
||||||
collectImmediately(pickerModel.currentSongsToAdd, ::updatePendingSongs)
|
collectImmediately(pickerModel.currentSongsToAdd, ::updatePendingSongs)
|
||||||
collectImmediately(pickerModel.playlistAddChoices, ::updatePlaylistChoices)
|
collectImmediately(pickerModel.playlistAddChoices, ::updatePlaylistChoices)
|
||||||
|
|
|
@ -71,6 +71,7 @@ class DeletePlaylistDialog : ViewBindingMaterialDialogFragment<DialogDeletePlayl
|
||||||
super.onBindingCreated(binding, savedInstanceState)
|
super.onBindingCreated(binding, savedInstanceState)
|
||||||
|
|
||||||
// --- VIEWMODEL SETUP ---
|
// --- VIEWMODEL SETUP ---
|
||||||
|
musicModel.playlistDecision.consume()
|
||||||
pickerModel.setPlaylistToDelete(args.playlistUid)
|
pickerModel.setPlaylistToDelete(args.playlistUid)
|
||||||
collectImmediately(pickerModel.currentPlaylistToDelete, ::updatePlaylistToDelete)
|
collectImmediately(pickerModel.currentPlaylistToDelete, ::updatePlaylistToDelete)
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,6 @@ import org.oxycblt.auxio.databinding.DialogPlaylistNameBinding
|
||||||
import org.oxycblt.auxio.music.MusicViewModel
|
import org.oxycblt.auxio.music.MusicViewModel
|
||||||
import org.oxycblt.auxio.ui.ViewBindingMaterialDialogFragment
|
import org.oxycblt.auxio.ui.ViewBindingMaterialDialogFragment
|
||||||
import org.oxycblt.auxio.util.collectImmediately
|
import org.oxycblt.auxio.util.collectImmediately
|
||||||
import org.oxycblt.auxio.util.logD
|
|
||||||
import org.oxycblt.auxio.util.showToast
|
import org.oxycblt.auxio.util.showToast
|
||||||
import org.oxycblt.auxio.util.unlikelyToBeNull
|
import org.oxycblt.auxio.util.unlikelyToBeNull
|
||||||
|
|
||||||
|
@ -83,21 +82,11 @@ class NewPlaylistDialog : ViewBindingMaterialDialogFragment<DialogPlaylistNameBi
|
||||||
binding.playlistName.addTextChangedListener { pickerModel.updateChosenName(it?.toString()) }
|
binding.playlistName.addTextChangedListener { pickerModel.updateChosenName(it?.toString()) }
|
||||||
|
|
||||||
// --- VIEWMODEL SETUP ---
|
// --- VIEWMODEL SETUP ---
|
||||||
|
musicModel.playlistDecision.consume()
|
||||||
pickerModel.setPendingPlaylist(requireContext(), args.songUids)
|
pickerModel.setPendingPlaylist(requireContext(), args.songUids)
|
||||||
collectImmediately(pickerModel.currentPendingPlaylist, ::updatePendingPlaylist)
|
|
||||||
collectImmediately(pickerModel.chosenName, ::updateChosenName)
|
collectImmediately(pickerModel.chosenName, ::updateChosenName)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updatePendingPlaylist(pendingPlaylist: PendingPlaylist?) {
|
|
||||||
if (pendingPlaylist == null) {
|
|
||||||
logD("No playlist to create, leaving")
|
|
||||||
findNavController().navigateUp()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
requireBinding().playlistName.hint = pendingPlaylist.preferredName
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun updateChosenName(chosenName: ChosenName) {
|
private fun updateChosenName(chosenName: ChosenName) {
|
||||||
(dialog as AlertDialog).getButton(AlertDialog.BUTTON_POSITIVE)?.isEnabled =
|
(dialog as AlertDialog).getButton(AlertDialog.BUTTON_POSITIVE)?.isEnabled =
|
||||||
chosenName is ChosenName.Valid || chosenName is ChosenName.Empty
|
chosenName is ChosenName.Valid || chosenName is ChosenName.Empty
|
||||||
|
|
|
@ -74,6 +74,7 @@ class RenamePlaylistDialog : ViewBindingMaterialDialogFragment<DialogPlaylistNam
|
||||||
binding.playlistName.addTextChangedListener { pickerModel.updateChosenName(it?.toString()) }
|
binding.playlistName.addTextChangedListener { pickerModel.updateChosenName(it?.toString()) }
|
||||||
|
|
||||||
// --- VIEWMODEL SETUP ---
|
// --- VIEWMODEL SETUP ---
|
||||||
|
musicModel.playlistDecision.consume()
|
||||||
pickerModel.setPlaylistToRename(args.playlistUid)
|
pickerModel.setPlaylistToRename(args.playlistUid)
|
||||||
collectImmediately(pickerModel.currentPlaylistToRename, ::updatePlaylistToRename)
|
collectImmediately(pickerModel.currentPlaylistToRename, ::updatePlaylistToRename)
|
||||||
collectImmediately(pickerModel.chosenName, ::updateChosenName)
|
collectImmediately(pickerModel.chosenName, ::updateChosenName)
|
||||||
|
|
|
@ -71,12 +71,12 @@ import org.oxycblt.auxio.util.setFullWidthLookup
|
||||||
*/
|
*/
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class SearchFragment : ListFragment<Music, FragmentSearchBinding>() {
|
class SearchFragment : ListFragment<Music, FragmentSearchBinding>() {
|
||||||
override val detailModel: DetailViewModel by activityViewModels()
|
private val searchModel: SearchViewModel by viewModels()
|
||||||
|
private val detailModel: DetailViewModel by activityViewModels()
|
||||||
private val menuModel: MenuViewModel by activityViewModels()
|
private val menuModel: MenuViewModel by activityViewModels()
|
||||||
override val selectionModel: SelectionViewModel by activityViewModels()
|
override val selectionModel: SelectionViewModel by activityViewModels()
|
||||||
override val playbackModel: PlaybackViewModel by activityViewModels()
|
override val playbackModel: PlaybackViewModel by activityViewModels()
|
||||||
override val musicModel: MusicViewModel by activityViewModels()
|
override val musicModel: MusicViewModel by activityViewModels()
|
||||||
private val searchModel: SearchViewModel by viewModels()
|
|
||||||
private val searchAdapter = SearchAdapter(this)
|
private val searchAdapter = SearchAdapter(this)
|
||||||
private var imm: InputMethodManager? = null
|
private var imm: InputMethodManager? = null
|
||||||
private var launchedKeyboard = false
|
private var launchedKeyboard = false
|
||||||
|
@ -236,12 +236,13 @@ class SearchFragment : ListFragment<Music, FragmentSearchBinding>() {
|
||||||
}
|
}
|
||||||
is Show.SongArtistDetails -> {
|
is Show.SongArtistDetails -> {
|
||||||
logD("Navigating to artist choices for ${show.song}")
|
logD("Navigating to artist choices for ${show.song}")
|
||||||
findNavController().navigateSafe(SearchFragmentDirections.showArtist(show.song.uid))
|
findNavController()
|
||||||
|
.navigateSafe(SearchFragmentDirections.showArtists(show.song.uid))
|
||||||
}
|
}
|
||||||
is Show.AlbumArtistDetails -> {
|
is Show.AlbumArtistDetails -> {
|
||||||
logD("Navigating to artist choices for ${show.album}")
|
logD("Navigating to artist choices for ${show.album}")
|
||||||
findNavController()
|
findNavController()
|
||||||
.navigateSafe(SearchFragmentDirections.showArtist(show.album.uid))
|
.navigateSafe(SearchFragmentDirections.showArtists(show.album.uid))
|
||||||
}
|
}
|
||||||
is Show.GenreDetails -> {
|
is Show.GenreDetails -> {
|
||||||
logD("Navigating to ${show.genre}")
|
logD("Navigating to ${show.genre}")
|
||||||
|
@ -281,7 +282,6 @@ class SearchFragment : ListFragment<Music, FragmentSearchBinding>() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
findNavController().navigateSafe(directions)
|
findNavController().navigateSafe(directions)
|
||||||
musicModel.playlistDecision.consume()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updatePlayback(song: Song?, parent: MusicParent?, isPlaying: Boolean) {
|
private fun updatePlayback(song: Song?, parent: MusicParent?, isPlaying: Boolean) {
|
||||||
|
@ -309,7 +309,6 @@ class SearchFragment : ListFragment<Music, FragmentSearchBinding>() {
|
||||||
pendingMenu.menuRes, pendingMenu.music.uid)
|
pendingMenu.menuRes, pendingMenu.music.uid)
|
||||||
}
|
}
|
||||||
findNavController().navigateSafe(directions)
|
findNavController().navigateSafe(directions)
|
||||||
menuModel.pendingMenu.consume()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateSelection(selected: List<Music>) {
|
private fun updateSelection(selected: List<Music>) {
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<item
|
<!-- <item-->
|
||||||
android:id="@+id/action_play"
|
<!-- android:id="@+id/action_play"-->
|
||||||
android:title="@string/lbl_play"
|
<!-- android:title="@string/lbl_play"-->
|
||||||
android:icon="@drawable/ic_play_24" />
|
<!-- android:icon="@drawable/ic_play_24" />-->
|
||||||
<item
|
<!-- <item-->
|
||||||
android:id="@+id/action_shuffle"
|
<!-- android:id="@+id/action_shuffle"-->
|
||||||
android:title="@string/lbl_shuffle"
|
<!-- android:title="@string/lbl_shuffle"-->
|
||||||
android:icon="@drawable/ic_shuffle_off_24"/>
|
<!-- android:icon="@drawable/ic_shuffle_off_24"/>-->
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_play_next"
|
android:id="@+id/action_play_next"
|
||||||
android:title="@string/lbl_play_next"
|
android:title="@string/lbl_play_next"
|
||||||
|
@ -30,5 +30,6 @@
|
||||||
android:icon="@drawable/ic_details_24" />
|
android:icon="@drawable/ic_details_24" />
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_share"
|
android:id="@+id/action_share"
|
||||||
android:title="@string/lbl_share" />
|
android:title="@string/lbl_share"
|
||||||
|
android:icon="@drawable/ic_share_24"/>
|
||||||
</menu>
|
</menu>
|
|
@ -1,13 +1,13 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<item
|
<!-- <item-->
|
||||||
android:id="@+id/action_play"
|
<!-- android:id="@+id/action_play"-->
|
||||||
android:title="@string/lbl_play"
|
<!-- android:title="@string/lbl_play"-->
|
||||||
android:icon="@drawable/ic_play_24" />
|
<!-- android:icon="@drawable/ic_play_24" />-->
|
||||||
<item
|
<!-- <item-->
|
||||||
android:id="@+id/action_shuffle"
|
<!-- android:id="@+id/action_shuffle"-->
|
||||||
android:title="@string/lbl_shuffle"
|
<!-- android:title="@string/lbl_shuffle"-->
|
||||||
android:icon="@drawable/ic_shuffle_off_24"/>
|
<!-- android:icon="@drawable/ic_shuffle_off_24"/>-->
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_play_next"
|
android:id="@+id/action_play_next"
|
||||||
android:title="@string/lbl_play_next"
|
android:title="@string/lbl_play_next"
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<item
|
<!-- <item-->
|
||||||
android:id="@+id/action_play"
|
<!-- android:id="@+id/action_play"-->
|
||||||
android:title="@string/lbl_play"
|
<!-- android:title="@string/lbl_play"-->
|
||||||
android:icon="@drawable/ic_play_24" />
|
<!-- android:icon="@drawable/ic_play_24" />-->
|
||||||
<item
|
<!-- <item-->
|
||||||
android:id="@+id/action_shuffle"
|
<!-- android:id="@+id/action_shuffle"-->
|
||||||
android:title="@string/lbl_shuffle"
|
<!-- android:title="@string/lbl_shuffle"-->
|
||||||
android:icon="@drawable/ic_shuffle_off_24" />
|
<!-- android:icon="@drawable/ic_shuffle_off_24" />-->
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_play_next"
|
android:id="@+id/action_play_next"
|
||||||
android:title="@string/lbl_play_next"
|
android:title="@string/lbl_play_next"
|
||||||
|
|
Loading…
Reference in a new issue