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 playingItem =
|
||||
when (parent) {
|
||||
// Always highlight a playing album if it's from this artist.
|
||||
is Album -> parent
|
||||
// Always highlight a playing album if it's from this artist, and if the currently
|
||||
// playing song is contained within.
|
||||
is Album -> parent.takeIf { song?.album == it }
|
||||
// If the parent is the artist itself, use the currently playing song.
|
||||
currentArtist -> song
|
||||
// Nothing is playing from this artist.
|
||||
else -> null
|
||||
}
|
||||
|
||||
artistListAdapter.setPlaying(playingItem, isPlaying)
|
||||
}
|
||||
|
||||
|
|
|
@ -239,15 +239,18 @@ class GenreDetailFragment :
|
|||
}
|
||||
|
||||
private fun updatePlayback(song: Song?, parent: MusicParent?, isPlaying: Boolean) {
|
||||
var playingMusic: Music? = null
|
||||
if (parent is Artist) {
|
||||
playingMusic = parent
|
||||
}
|
||||
// Prefer songs that might be playing from this genre.
|
||||
if (parent is Genre && parent.uid == unlikelyToBeNull(detailModel.currentGenre.value).uid) {
|
||||
playingMusic = song
|
||||
}
|
||||
genreListAdapter.setPlaying(playingMusic, isPlaying)
|
||||
val currentGenre = unlikelyToBeNull(detailModel.currentGenre.value)
|
||||
val playingItem =
|
||||
when (parent) {
|
||||
// Always highlight a playing artist if it's from this genre, and if the currently
|
||||
// playing song is contained within.
|
||||
is Artist -> parent.takeIf { song?.run { artists.contains(it) } ?: false }
|
||||
// If the parent is the artist itself, use the currently playing song.
|
||||
currentGenre -> song
|
||||
// Nothing is playing from this artist.
|
||||
else -> null
|
||||
}
|
||||
genreListAdapter.setPlaying(playingItem, isPlaying)
|
||||
}
|
||||
|
||||
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.MusicParent
|
||||
import org.oxycblt.auxio.music.MusicViewModel
|
||||
import org.oxycblt.auxio.music.Song
|
||||
import org.oxycblt.auxio.navigation.NavigationViewModel
|
||||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||
import org.oxycblt.auxio.playback.formatDurationMs
|
||||
|
@ -82,7 +83,8 @@ class AlbumListFragment :
|
|||
|
||||
collectImmediately(homeModel.albumsList, ::updateAlbums)
|
||||
collectImmediately(selectionModel.selected, ::updateSelection)
|
||||
collectImmediately(playbackModel.parent, playbackModel.isPlaying, ::updatePlayback)
|
||||
collectImmediately(
|
||||
playbackModel.song, playbackModel.parent, playbackModel.isPlaying, ::updatePlayback)
|
||||
}
|
||||
|
||||
override fun onDestroyBinding(binding: FragmentHomeListBinding) {
|
||||
|
@ -151,9 +153,11 @@ class AlbumListFragment :
|
|||
albumAdapter.setSelected(selection.filterIsInstanceTo(mutableSetOf()))
|
||||
}
|
||||
|
||||
private fun updatePlayback(parent: MusicParent?, isPlaying: Boolean) {
|
||||
// If an album is playing, highlight it within this adapter.
|
||||
albumAdapter.setPlaying(parent as? Album, isPlaying)
|
||||
private fun updatePlayback(song: Song?, parent: MusicParent?, isPlaying: Boolean) {
|
||||
// Only highlight the album if it is currently playing, and if the currently
|
||||
// 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.MusicParent
|
||||
import org.oxycblt.auxio.music.MusicViewModel
|
||||
import org.oxycblt.auxio.music.Song
|
||||
import org.oxycblt.auxio.navigation.NavigationViewModel
|
||||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||
import org.oxycblt.auxio.playback.formatDurationMs
|
||||
|
@ -78,7 +79,8 @@ class ArtistListFragment :
|
|||
|
||||
collectImmediately(homeModel.artistsList, ::updateArtists)
|
||||
collectImmediately(selectionModel.selected, ::updateSelection)
|
||||
collectImmediately(playbackModel.parent, playbackModel.isPlaying, ::updatePlayback)
|
||||
collectImmediately(
|
||||
playbackModel.song, playbackModel.parent, playbackModel.isPlaying, ::updatePlayback)
|
||||
}
|
||||
|
||||
override fun onDestroyBinding(binding: FragmentHomeListBinding) {
|
||||
|
@ -128,9 +130,11 @@ class ArtistListFragment :
|
|||
artistAdapter.setSelected(selection.filterIsInstanceTo(mutableSetOf()))
|
||||
}
|
||||
|
||||
private fun updatePlayback(parent: MusicParent?, isPlaying: Boolean) {
|
||||
// If an artist is playing, highlight it within this adapter.
|
||||
artistAdapter.setPlaying(parent as? Artist, isPlaying)
|
||||
private fun updatePlayback(song: Song?, parent: MusicParent?, isPlaying: Boolean) {
|
||||
// Only highlight the artist if it is currently playing, and if the currently
|
||||
// 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.MusicParent
|
||||
import org.oxycblt.auxio.music.MusicViewModel
|
||||
import org.oxycblt.auxio.music.Song
|
||||
import org.oxycblt.auxio.navigation.NavigationViewModel
|
||||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||
import org.oxycblt.auxio.playback.formatDurationMs
|
||||
|
@ -77,7 +78,8 @@ class GenreListFragment :
|
|||
|
||||
collectImmediately(homeModel.genresList, ::updateGenres)
|
||||
collectImmediately(selectionModel.selected, ::updateSelection)
|
||||
collectImmediately(playbackModel.parent, playbackModel.isPlaying, ::updatePlayback)
|
||||
collectImmediately(
|
||||
playbackModel.song, playbackModel.parent, playbackModel.isPlaying, ::updatePlayback)
|
||||
}
|
||||
|
||||
override fun onDestroyBinding(binding: FragmentHomeListBinding) {
|
||||
|
@ -127,9 +129,11 @@ class GenreListFragment :
|
|||
genreAdapter.setSelected(selection.filterIsInstanceTo(mutableSetOf()))
|
||||
}
|
||||
|
||||
private fun updatePlayback(parent: MusicParent?, isPlaying: Boolean) {
|
||||
// If a genre is playing, highlight it within this adapter.
|
||||
genreAdapter.setPlaying(parent as? Genre, isPlaying)
|
||||
private fun updatePlayback(song: Song?, parent: MusicParent?, isPlaying: Boolean) {
|
||||
// Only highlight the genre if it is currently playing, and if the currently
|
||||
// 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.MusicViewModel
|
||||
import org.oxycblt.auxio.music.Playlist
|
||||
import org.oxycblt.auxio.music.Song
|
||||
import org.oxycblt.auxio.navigation.NavigationViewModel
|
||||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||
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.
|
||||
*
|
||||
* @author Alexander Capehart (OxygenCobalt)
|
||||
*
|
||||
* TODO: Show a placeholder when there are no playlists.
|
||||
*/
|
||||
class PlaylistListFragment :
|
||||
ListFragment<Playlist, FragmentHomeListBinding>(),
|
||||
|
@ -77,7 +76,8 @@ class PlaylistListFragment :
|
|||
|
||||
collectImmediately(homeModel.playlistsList, ::updatePlaylists)
|
||||
collectImmediately(selectionModel.selected, ::updateSelection)
|
||||
collectImmediately(playbackModel.parent, playbackModel.isPlaying, ::updatePlayback)
|
||||
collectImmediately(
|
||||
playbackModel.song, playbackModel.parent, playbackModel.isPlaying, ::updatePlayback)
|
||||
}
|
||||
|
||||
override fun onDestroyBinding(binding: FragmentHomeListBinding) {
|
||||
|
@ -128,9 +128,11 @@ class PlaylistListFragment :
|
|||
playlistAdapter.setSelected(selection.filterIsInstanceTo(mutableSetOf()))
|
||||
}
|
||||
|
||||
private fun updatePlayback(parent: MusicParent?, isPlaying: Boolean) {
|
||||
// If a playlist is playing, highlight it within this adapter.
|
||||
playlistAdapter.setPlaying(parent as? Playlist, isPlaying)
|
||||
private fun updatePlayback(song: Song?, parent: MusicParent?, isPlaying: Boolean) {
|
||||
// Only highlight the playlist if it is currently playing, and if the currently
|
||||
// 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) {
|
||||
if (parent == null) {
|
||||
songAdapter.setPlaying(song, isPlaying)
|
||||
} else {
|
||||
// Ignore playback that is not from all songs
|
||||
songAdapter.setPlaying(null, isPlaying)
|
||||
}
|
||||
// Only indicate playback that is from all songs
|
||||
songAdapter.setPlaying(song.takeIf { parent == null }, isPlaying)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue