playback: fix broken item navigation
Caused yet again by sharing StateFlows leading to a strange out-of-order collector notification, which then allows detail fragments to consume item navigation requests before the playback panel can even get them. SharedFlow doesn't help here, so we are just forced to move this to MainFragment which does not have this issue for some reason.
This commit is contained in:
parent
20c34fd888
commit
d0b34a14e4
2 changed files with 22 additions and 23 deletions
|
@ -38,6 +38,7 @@ import kotlin.math.max
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
import org.oxycblt.auxio.databinding.FragmentMainBinding
|
import org.oxycblt.auxio.databinding.FragmentMainBinding
|
||||||
import org.oxycblt.auxio.detail.DetailViewModel
|
import org.oxycblt.auxio.detail.DetailViewModel
|
||||||
|
import org.oxycblt.auxio.detail.Show
|
||||||
import org.oxycblt.auxio.home.HomeViewModel
|
import org.oxycblt.auxio.home.HomeViewModel
|
||||||
import org.oxycblt.auxio.home.Outer
|
import org.oxycblt.auxio.home.Outer
|
||||||
import org.oxycblt.auxio.list.ListViewModel
|
import org.oxycblt.auxio.list.ListViewModel
|
||||||
|
@ -49,6 +50,7 @@ import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||||
import org.oxycblt.auxio.playback.queue.QueueBottomSheetBehavior
|
import org.oxycblt.auxio.playback.queue.QueueBottomSheetBehavior
|
||||||
import org.oxycblt.auxio.ui.DialogAwareNavigationListener
|
import org.oxycblt.auxio.ui.DialogAwareNavigationListener
|
||||||
import org.oxycblt.auxio.ui.ViewBindingFragment
|
import org.oxycblt.auxio.ui.ViewBindingFragment
|
||||||
|
import org.oxycblt.auxio.util.collect
|
||||||
import org.oxycblt.auxio.util.collectImmediately
|
import org.oxycblt.auxio.util.collectImmediately
|
||||||
import org.oxycblt.auxio.util.context
|
import org.oxycblt.auxio.util.context
|
||||||
import org.oxycblt.auxio.util.coordinatorLayoutBehavior
|
import org.oxycblt.auxio.util.coordinatorLayoutBehavior
|
||||||
|
@ -149,6 +151,11 @@ class MainFragment :
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- VIEWMODEL SETUP ---
|
// --- VIEWMODEL SETUP ---
|
||||||
|
// This has to be done here instead of the playback panel to make sure that it's prioritized
|
||||||
|
// by StateFlow over any detail fragment.
|
||||||
|
// FIXME: This is a consequence of sharing events across several consumers. There has to be
|
||||||
|
// a better way of doing this.
|
||||||
|
collect(detailModel.toShow.flow, ::handleShow)
|
||||||
collectImmediately(detailModel.editedPlaylist, detailBackCallback::invalidateEnabled)
|
collectImmediately(detailModel.editedPlaylist, detailBackCallback::invalidateEnabled)
|
||||||
collectImmediately(homeModel.showOuter.flow, ::handleShowOuter)
|
collectImmediately(homeModel.showOuter.flow, ::handleShowOuter)
|
||||||
collectImmediately(listModel.selected, selectionBackCallback::invalidateEnabled)
|
collectImmediately(listModel.selected, selectionBackCallback::invalidateEnabled)
|
||||||
|
@ -287,6 +294,20 @@ class MainFragment :
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun handleShow(show: Show?) {
|
||||||
|
when (show) {
|
||||||
|
is Show.SongAlbumDetails,
|
||||||
|
is Show.ArtistDetails,
|
||||||
|
is Show.AlbumDetails -> playbackModel.openMain()
|
||||||
|
is Show.SongDetails,
|
||||||
|
is Show.SongArtistDecision,
|
||||||
|
is Show.AlbumArtistDecision,
|
||||||
|
is Show.GenreDetails,
|
||||||
|
is Show.PlaylistDetails,
|
||||||
|
null -> {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun handleShowOuter(outer: Outer?) {
|
private fun handleShowOuter(outer: Outer?) {
|
||||||
val directions =
|
val directions =
|
||||||
when (outer) {
|
when (outer) {
|
||||||
|
|
|
@ -33,7 +33,6 @@ import dagger.hilt.android.AndroidEntryPoint
|
||||||
import org.oxycblt.auxio.R
|
import org.oxycblt.auxio.R
|
||||||
import org.oxycblt.auxio.databinding.FragmentPlaybackPanelBinding
|
import org.oxycblt.auxio.databinding.FragmentPlaybackPanelBinding
|
||||||
import org.oxycblt.auxio.detail.DetailViewModel
|
import org.oxycblt.auxio.detail.DetailViewModel
|
||||||
import org.oxycblt.auxio.detail.Show
|
|
||||||
import org.oxycblt.auxio.list.ListViewModel
|
import org.oxycblt.auxio.list.ListViewModel
|
||||||
import org.oxycblt.auxio.music.MusicParent
|
import org.oxycblt.auxio.music.MusicParent
|
||||||
import org.oxycblt.auxio.music.Song
|
import org.oxycblt.auxio.music.Song
|
||||||
|
@ -41,7 +40,6 @@ import org.oxycblt.auxio.music.resolveNames
|
||||||
import org.oxycblt.auxio.playback.state.RepeatMode
|
import org.oxycblt.auxio.playback.state.RepeatMode
|
||||||
import org.oxycblt.auxio.playback.ui.StyledSeekBar
|
import org.oxycblt.auxio.playback.ui.StyledSeekBar
|
||||||
import org.oxycblt.auxio.ui.ViewBindingFragment
|
import org.oxycblt.auxio.ui.ViewBindingFragment
|
||||||
import org.oxycblt.auxio.util.collect
|
|
||||||
import org.oxycblt.auxio.util.collectImmediately
|
import org.oxycblt.auxio.util.collectImmediately
|
||||||
import org.oxycblt.auxio.util.logD
|
import org.oxycblt.auxio.util.logD
|
||||||
import org.oxycblt.auxio.util.overrideOnOverflowMenuClick
|
import org.oxycblt.auxio.util.overrideOnOverflowMenuClick
|
||||||
|
@ -105,12 +103,7 @@ class PlaybackPanelFragment :
|
||||||
// respective item.
|
// respective item.
|
||||||
binding.playbackSong.apply {
|
binding.playbackSong.apply {
|
||||||
isSelected = true
|
isSelected = true
|
||||||
setOnClickListener {
|
setOnClickListener { playbackModel.song.value?.let(detailModel::showAlbum) }
|
||||||
playbackModel.song.value?.let {
|
|
||||||
detailModel.showAlbum(it)
|
|
||||||
playbackModel.openMain()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
binding.playbackArtist.apply {
|
binding.playbackArtist.apply {
|
||||||
isSelected = true
|
isSelected = true
|
||||||
|
@ -138,7 +131,6 @@ class PlaybackPanelFragment :
|
||||||
collectImmediately(playbackModel.repeatMode, ::updateRepeat)
|
collectImmediately(playbackModel.repeatMode, ::updateRepeat)
|
||||||
collectImmediately(playbackModel.isPlaying, ::updatePlaying)
|
collectImmediately(playbackModel.isPlaying, ::updatePlaying)
|
||||||
collectImmediately(playbackModel.isShuffled, ::updateShuffled)
|
collectImmediately(playbackModel.isShuffled, ::updateShuffled)
|
||||||
collect(detailModel.toShow.flow, ::handleShow)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyBinding(binding: FragmentPlaybackPanelBinding) {
|
override fun onDestroyBinding(binding: FragmentPlaybackPanelBinding) {
|
||||||
|
@ -220,20 +212,6 @@ class PlaybackPanelFragment :
|
||||||
requireBinding().playbackShuffle.isActivated = isShuffled
|
requireBinding().playbackShuffle.isActivated = isShuffled
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleShow(show: Show?) {
|
|
||||||
when (show) {
|
|
||||||
is Show.SongAlbumDetails,
|
|
||||||
is Show.ArtistDetails,
|
|
||||||
is Show.AlbumDetails -> playbackModel.openMain()
|
|
||||||
is Show.SongDetails,
|
|
||||||
is Show.SongArtistDecision,
|
|
||||||
is Show.AlbumArtistDecision,
|
|
||||||
is Show.GenreDetails,
|
|
||||||
is Show.PlaylistDetails,
|
|
||||||
null -> {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun navigateToCurrentArtist() {
|
private fun navigateToCurrentArtist() {
|
||||||
playbackModel.song.value?.let(detailModel::showArtist)
|
playbackModel.song.value?.let(detailModel::showArtist)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue