ui: handle playing indicator edge cases
Handle two edge cases identified with the playing indicator behavior: 1. When enqueing songs from another parent, the prior parent is still indicates as "playing" when it kind-of isn't. 2. When playback is stopped, the parent is not reset, and thus will still be indicated as "playing" after the song has disappeared. This is rarer and should be resolved in other ways, but the solution to 1 also fixes this. Resolves #380.
This commit is contained in:
parent
21a6b97bfa
commit
c2def19aee
7 changed files with 49 additions and 36 deletions
|
@ -254,14 +254,14 @@ class ArtistDetailFragment :
|
||||||
val currentArtist = unlikelyToBeNull(detailModel.currentArtist.value)
|
val currentArtist = unlikelyToBeNull(detailModel.currentArtist.value)
|
||||||
val playingItem =
|
val playingItem =
|
||||||
when (parent) {
|
when (parent) {
|
||||||
// Always highlight a playing album if it's from this artist.
|
// Always highlight a playing album if it's from this artist, and if the currently
|
||||||
is Album -> parent
|
// playing song is contained within.
|
||||||
|
is Album -> parent.takeIf { song?.album == it }
|
||||||
// If the parent is the artist itself, use the currently playing song.
|
// If the parent is the artist itself, use the currently playing song.
|
||||||
currentArtist -> song
|
currentArtist -> song
|
||||||
// Nothing is playing from this artist.
|
// Nothing is playing from this artist.
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
|
||||||
artistListAdapter.setPlaying(playingItem, isPlaying)
|
artistListAdapter.setPlaying(playingItem, isPlaying)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -239,15 +239,18 @@ class GenreDetailFragment :
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updatePlayback(song: Song?, parent: MusicParent?, isPlaying: Boolean) {
|
private fun updatePlayback(song: Song?, parent: MusicParent?, isPlaying: Boolean) {
|
||||||
var playingMusic: Music? = null
|
val currentGenre = unlikelyToBeNull(detailModel.currentGenre.value)
|
||||||
if (parent is Artist) {
|
val playingItem =
|
||||||
playingMusic = parent
|
when (parent) {
|
||||||
}
|
// Always highlight a playing artist if it's from this genre, and if the currently
|
||||||
// Prefer songs that might be playing from this genre.
|
// playing song is contained within.
|
||||||
if (parent is Genre && parent.uid == unlikelyToBeNull(detailModel.currentGenre.value).uid) {
|
is Artist -> parent.takeIf { song?.run { artists.contains(it) } ?: false }
|
||||||
playingMusic = song
|
// If the parent is the artist itself, use the currently playing song.
|
||||||
}
|
currentGenre -> song
|
||||||
genreListAdapter.setPlaying(playingMusic, isPlaying)
|
// Nothing is playing from this artist.
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
genreListAdapter.setPlaying(playingItem, isPlaying)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleNavigation(item: Music?) {
|
private fun handleNavigation(item: Music?) {
|
||||||
|
|
|
@ -41,6 +41,7 @@ import org.oxycblt.auxio.music.Music
|
||||||
import org.oxycblt.auxio.music.MusicMode
|
import org.oxycblt.auxio.music.MusicMode
|
||||||
import org.oxycblt.auxio.music.MusicParent
|
import org.oxycblt.auxio.music.MusicParent
|
||||||
import org.oxycblt.auxio.music.MusicViewModel
|
import org.oxycblt.auxio.music.MusicViewModel
|
||||||
|
import org.oxycblt.auxio.music.Song
|
||||||
import org.oxycblt.auxio.navigation.NavigationViewModel
|
import org.oxycblt.auxio.navigation.NavigationViewModel
|
||||||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||||
import org.oxycblt.auxio.playback.formatDurationMs
|
import org.oxycblt.auxio.playback.formatDurationMs
|
||||||
|
@ -82,7 +83,8 @@ class AlbumListFragment :
|
||||||
|
|
||||||
collectImmediately(homeModel.albumsList, ::updateAlbums)
|
collectImmediately(homeModel.albumsList, ::updateAlbums)
|
||||||
collectImmediately(selectionModel.selected, ::updateSelection)
|
collectImmediately(selectionModel.selected, ::updateSelection)
|
||||||
collectImmediately(playbackModel.parent, playbackModel.isPlaying, ::updatePlayback)
|
collectImmediately(
|
||||||
|
playbackModel.song, playbackModel.parent, playbackModel.isPlaying, ::updatePlayback)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyBinding(binding: FragmentHomeListBinding) {
|
override fun onDestroyBinding(binding: FragmentHomeListBinding) {
|
||||||
|
@ -151,9 +153,11 @@ class AlbumListFragment :
|
||||||
albumAdapter.setSelected(selection.filterIsInstanceTo(mutableSetOf()))
|
albumAdapter.setSelected(selection.filterIsInstanceTo(mutableSetOf()))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updatePlayback(parent: MusicParent?, isPlaying: Boolean) {
|
private fun updatePlayback(song: Song?, parent: MusicParent?, isPlaying: Boolean) {
|
||||||
// If an album is playing, highlight it within this adapter.
|
// Only highlight the album if it is currently playing, and if the currently
|
||||||
albumAdapter.setPlaying(parent as? Album, isPlaying)
|
// playing song is also contained within.
|
||||||
|
val playlist = (parent as? Album)?.takeIf { song?.album == it }
|
||||||
|
albumAdapter.setPlaying(playlist, isPlaying)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -39,6 +39,7 @@ import org.oxycblt.auxio.music.Music
|
||||||
import org.oxycblt.auxio.music.MusicMode
|
import org.oxycblt.auxio.music.MusicMode
|
||||||
import org.oxycblt.auxio.music.MusicParent
|
import org.oxycblt.auxio.music.MusicParent
|
||||||
import org.oxycblt.auxio.music.MusicViewModel
|
import org.oxycblt.auxio.music.MusicViewModel
|
||||||
|
import org.oxycblt.auxio.music.Song
|
||||||
import org.oxycblt.auxio.navigation.NavigationViewModel
|
import org.oxycblt.auxio.navigation.NavigationViewModel
|
||||||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||||
import org.oxycblt.auxio.playback.formatDurationMs
|
import org.oxycblt.auxio.playback.formatDurationMs
|
||||||
|
@ -78,7 +79,8 @@ class ArtistListFragment :
|
||||||
|
|
||||||
collectImmediately(homeModel.artistsList, ::updateArtists)
|
collectImmediately(homeModel.artistsList, ::updateArtists)
|
||||||
collectImmediately(selectionModel.selected, ::updateSelection)
|
collectImmediately(selectionModel.selected, ::updateSelection)
|
||||||
collectImmediately(playbackModel.parent, playbackModel.isPlaying, ::updatePlayback)
|
collectImmediately(
|
||||||
|
playbackModel.song, playbackModel.parent, playbackModel.isPlaying, ::updatePlayback)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyBinding(binding: FragmentHomeListBinding) {
|
override fun onDestroyBinding(binding: FragmentHomeListBinding) {
|
||||||
|
@ -128,9 +130,11 @@ class ArtistListFragment :
|
||||||
artistAdapter.setSelected(selection.filterIsInstanceTo(mutableSetOf()))
|
artistAdapter.setSelected(selection.filterIsInstanceTo(mutableSetOf()))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updatePlayback(parent: MusicParent?, isPlaying: Boolean) {
|
private fun updatePlayback(song: Song?, parent: MusicParent?, isPlaying: Boolean) {
|
||||||
// If an artist is playing, highlight it within this adapter.
|
// Only highlight the artist if it is currently playing, and if the currently
|
||||||
artistAdapter.setPlaying(parent as? Artist, isPlaying)
|
// playing song is also contained within.
|
||||||
|
val playlist = (parent as? Artist)?.takeIf { song?.run { artists.contains(it) } ?: false }
|
||||||
|
artistAdapter.setPlaying(playlist, isPlaying)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -39,6 +39,7 @@ import org.oxycblt.auxio.music.Music
|
||||||
import org.oxycblt.auxio.music.MusicMode
|
import org.oxycblt.auxio.music.MusicMode
|
||||||
import org.oxycblt.auxio.music.MusicParent
|
import org.oxycblt.auxio.music.MusicParent
|
||||||
import org.oxycblt.auxio.music.MusicViewModel
|
import org.oxycblt.auxio.music.MusicViewModel
|
||||||
|
import org.oxycblt.auxio.music.Song
|
||||||
import org.oxycblt.auxio.navigation.NavigationViewModel
|
import org.oxycblt.auxio.navigation.NavigationViewModel
|
||||||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||||
import org.oxycblt.auxio.playback.formatDurationMs
|
import org.oxycblt.auxio.playback.formatDurationMs
|
||||||
|
@ -77,7 +78,8 @@ class GenreListFragment :
|
||||||
|
|
||||||
collectImmediately(homeModel.genresList, ::updateGenres)
|
collectImmediately(homeModel.genresList, ::updateGenres)
|
||||||
collectImmediately(selectionModel.selected, ::updateSelection)
|
collectImmediately(selectionModel.selected, ::updateSelection)
|
||||||
collectImmediately(playbackModel.parent, playbackModel.isPlaying, ::updatePlayback)
|
collectImmediately(
|
||||||
|
playbackModel.song, playbackModel.parent, playbackModel.isPlaying, ::updatePlayback)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyBinding(binding: FragmentHomeListBinding) {
|
override fun onDestroyBinding(binding: FragmentHomeListBinding) {
|
||||||
|
@ -127,9 +129,11 @@ class GenreListFragment :
|
||||||
genreAdapter.setSelected(selection.filterIsInstanceTo(mutableSetOf()))
|
genreAdapter.setSelected(selection.filterIsInstanceTo(mutableSetOf()))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updatePlayback(parent: MusicParent?, isPlaying: Boolean) {
|
private fun updatePlayback(song: Song?, parent: MusicParent?, isPlaying: Boolean) {
|
||||||
// If a genre is playing, highlight it within this adapter.
|
// Only highlight the genre if it is currently playing, and if the currently
|
||||||
genreAdapter.setPlaying(parent as? Genre, isPlaying)
|
// playing song is also contained within.
|
||||||
|
val playlist = (parent as? Genre)?.takeIf { song?.run { genres.contains(it) } ?: false }
|
||||||
|
genreAdapter.setPlaying(playlist, isPlaying)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -38,6 +38,7 @@ import org.oxycblt.auxio.music.MusicMode
|
||||||
import org.oxycblt.auxio.music.MusicParent
|
import org.oxycblt.auxio.music.MusicParent
|
||||||
import org.oxycblt.auxio.music.MusicViewModel
|
import org.oxycblt.auxio.music.MusicViewModel
|
||||||
import org.oxycblt.auxio.music.Playlist
|
import org.oxycblt.auxio.music.Playlist
|
||||||
|
import org.oxycblt.auxio.music.Song
|
||||||
import org.oxycblt.auxio.navigation.NavigationViewModel
|
import org.oxycblt.auxio.navigation.NavigationViewModel
|
||||||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||||
import org.oxycblt.auxio.playback.formatDurationMs
|
import org.oxycblt.auxio.playback.formatDurationMs
|
||||||
|
@ -48,8 +49,6 @@ import org.oxycblt.auxio.util.logD
|
||||||
* A [ListFragment] that shows a list of [Playlist]s.
|
* A [ListFragment] that shows a list of [Playlist]s.
|
||||||
*
|
*
|
||||||
* @author Alexander Capehart (OxygenCobalt)
|
* @author Alexander Capehart (OxygenCobalt)
|
||||||
*
|
|
||||||
* TODO: Show a placeholder when there are no playlists.
|
|
||||||
*/
|
*/
|
||||||
class PlaylistListFragment :
|
class PlaylistListFragment :
|
||||||
ListFragment<Playlist, FragmentHomeListBinding>(),
|
ListFragment<Playlist, FragmentHomeListBinding>(),
|
||||||
|
@ -77,7 +76,8 @@ class PlaylistListFragment :
|
||||||
|
|
||||||
collectImmediately(homeModel.playlistsList, ::updatePlaylists)
|
collectImmediately(homeModel.playlistsList, ::updatePlaylists)
|
||||||
collectImmediately(selectionModel.selected, ::updateSelection)
|
collectImmediately(selectionModel.selected, ::updateSelection)
|
||||||
collectImmediately(playbackModel.parent, playbackModel.isPlaying, ::updatePlayback)
|
collectImmediately(
|
||||||
|
playbackModel.song, playbackModel.parent, playbackModel.isPlaying, ::updatePlayback)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyBinding(binding: FragmentHomeListBinding) {
|
override fun onDestroyBinding(binding: FragmentHomeListBinding) {
|
||||||
|
@ -128,9 +128,11 @@ class PlaylistListFragment :
|
||||||
playlistAdapter.setSelected(selection.filterIsInstanceTo(mutableSetOf()))
|
playlistAdapter.setSelected(selection.filterIsInstanceTo(mutableSetOf()))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updatePlayback(parent: MusicParent?, isPlaying: Boolean) {
|
private fun updatePlayback(song: Song?, parent: MusicParent?, isPlaying: Boolean) {
|
||||||
// If a playlist is playing, highlight it within this adapter.
|
// Only highlight the playlist if it is currently playing, and if the currently
|
||||||
playlistAdapter.setPlaying(parent as? Playlist, isPlaying)
|
// playing song is also contained within.
|
||||||
|
val playlist = (parent as? Playlist)?.takeIf { it.songs.contains(song) } ?: return
|
||||||
|
playlistAdapter.setPlaying(playlist, isPlaying)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -155,12 +155,8 @@ class SongListFragment :
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updatePlayback(song: Song?, parent: MusicParent?, isPlaying: Boolean) {
|
private fun updatePlayback(song: Song?, parent: MusicParent?, isPlaying: Boolean) {
|
||||||
if (parent == null) {
|
// Only indicate playback that is from all songs
|
||||||
songAdapter.setPlaying(song, isPlaying)
|
songAdapter.setPlaying(song.takeIf { parent == null }, isPlaying)
|
||||||
} else {
|
|
||||||
// Ignore playback that is not from all songs
|
|
||||||
songAdapter.setPlaying(null, isPlaying)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue