detail: improve playlist presentation
Improve playlist presentation in the detail views, especially when it is empty.
This commit is contained in:
parent
7435165929
commit
949a9c879c
7 changed files with 62 additions and 34 deletions
|
@ -46,6 +46,8 @@ import org.oxycblt.auxio.util.*
|
|||
* [ViewModel] that manages the Song, Album, Artist, and Genre detail views. Keeps track of the
|
||||
* current item they are showing, sub-data to display, and configuration.
|
||||
*
|
||||
* FIXME: Need to do direct item comparison in equality checks, or reset on navigation.
|
||||
*
|
||||
* @author Alexander Capehart (OxygenCobalt)
|
||||
*/
|
||||
@HiltViewModel
|
||||
|
@ -416,15 +418,16 @@ constructor(
|
|||
|
||||
private fun refreshPlaylistList(playlist: Playlist, replace: Boolean = false) {
|
||||
logD("Refreshing playlist list")
|
||||
var instructions: UpdateInstructions = UpdateInstructions.Diff
|
||||
val list = mutableListOf<Item>()
|
||||
list.add(SortHeader(R.string.lbl_songs))
|
||||
val instructions =
|
||||
|
||||
if (playlist.songs.isNotEmpty()) {
|
||||
list.add(SortHeader(R.string.lbl_songs))
|
||||
if (replace) {
|
||||
UpdateInstructions.Replace(list.size)
|
||||
} else {
|
||||
UpdateInstructions.Diff
|
||||
instructions = UpdateInstructions.Replace(list.size)
|
||||
}
|
||||
list.addAll(playlistSongSort.songs(playlist.songs))
|
||||
list.addAll(playlistSongSort.songs(playlist.songs))
|
||||
}
|
||||
_playlistInstructions.put(instructions)
|
||||
_playlistList.value = list
|
||||
}
|
||||
|
|
|
@ -65,6 +65,17 @@ private constructor(private val binding: ItemDetailHeaderBinding) :
|
|||
binding.detailType.text = binding.context.getString(R.string.lbl_artist)
|
||||
binding.detailName.text = artist.name.resolve(binding.context)
|
||||
|
||||
// Song and album counts map to the info
|
||||
binding.detailInfo.text =
|
||||
binding.context.getString(
|
||||
R.string.fmt_two,
|
||||
binding.context.getPlural(R.plurals.fmt_album_count, artist.albums.size),
|
||||
if (artist.songs.isNotEmpty()) {
|
||||
binding.context.getPlural(R.plurals.fmt_song_count, artist.songs.size)
|
||||
} else {
|
||||
binding.context.getString(R.string.def_song_count)
|
||||
})
|
||||
|
||||
if (artist.songs.isNotEmpty()) {
|
||||
// Information about the artist's genre(s) map to the sub-head text
|
||||
binding.detailSubhead.apply {
|
||||
|
@ -72,13 +83,6 @@ private constructor(private val binding: ItemDetailHeaderBinding) :
|
|||
text = artist.genres.resolveNames(context)
|
||||
}
|
||||
|
||||
// Song and album counts map to the info
|
||||
binding.detailInfo.text =
|
||||
binding.context.getString(
|
||||
R.string.fmt_two,
|
||||
binding.context.getPlural(R.plurals.fmt_album_count, artist.albums.size),
|
||||
binding.context.getPlural(R.plurals.fmt_song_count, artist.songs.size))
|
||||
|
||||
// In the case that this header used to he configured to have no songs,
|
||||
// we want to reset the visibility of all information that was hidden.
|
||||
binding.detailPlayButton.isVisible = true
|
||||
|
@ -88,10 +92,8 @@ private constructor(private val binding: ItemDetailHeaderBinding) :
|
|||
// ex. Play and Shuffle, Song Counts, and Genre Information.
|
||||
// Artists are always guaranteed to have albums however, so continue to show those.
|
||||
binding.detailSubhead.isVisible = false
|
||||
binding.detailInfo.text =
|
||||
binding.context.getPlural(R.plurals.fmt_album_count, artist.albums.size)
|
||||
binding.detailPlayButton.isVisible = false
|
||||
binding.detailShuffleButton.isVisible = false
|
||||
binding.detailPlayButton.isEnabled = false
|
||||
binding.detailShuffleButton.isEnabled = false
|
||||
}
|
||||
|
||||
binding.detailPlayButton.setOnClickListener { listener.onPlay() }
|
||||
|
|
|
@ -65,11 +65,26 @@ private constructor(private val binding: ItemDetailHeaderBinding) :
|
|||
binding.detailName.text = playlist.name.resolve(binding.context)
|
||||
// Nothing about a playlist is applicable to the sub-head text.
|
||||
binding.detailSubhead.isVisible = false
|
||||
|
||||
// The song count of the playlist maps to the info text.
|
||||
binding.detailInfo.text =
|
||||
binding.context.getPlural(R.plurals.fmt_song_count, playlist.songs.size)
|
||||
binding.detailPlayButton.setOnClickListener { listener.onPlay() }
|
||||
binding.detailShuffleButton.setOnClickListener { listener.onShuffle() }
|
||||
binding.detailInfo.apply {
|
||||
isVisible = true
|
||||
text =
|
||||
if (playlist.songs.isNotEmpty()) {
|
||||
binding.context.getPlural(R.plurals.fmt_song_count, playlist.songs.size)
|
||||
} else {
|
||||
binding.context.getString(R.string.def_song_count)
|
||||
}
|
||||
}
|
||||
|
||||
binding.detailPlayButton.apply {
|
||||
isEnabled = playlist.songs.isNotEmpty()
|
||||
setOnClickListener { listener.onPlay() }
|
||||
}
|
||||
binding.detailShuffleButton.apply {
|
||||
isEnabled = playlist.songs.isNotEmpty()
|
||||
setOnClickListener { listener.onShuffle() }
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
@ -157,15 +157,14 @@ class ArtistViewHolder private constructor(private val binding: ItemParentBindin
|
|||
binding.parentImage.bind(artist)
|
||||
binding.parentName.text = artist.name.resolve(binding.context)
|
||||
binding.parentInfo.text =
|
||||
if (artist.songs.isNotEmpty()) {
|
||||
binding.context.getString(
|
||||
R.string.fmt_two,
|
||||
binding.context.getPlural(R.plurals.fmt_album_count, artist.albums.size),
|
||||
binding.context.getPlural(R.plurals.fmt_song_count, artist.songs.size))
|
||||
} else {
|
||||
// Artist has no songs, only display an album count.
|
||||
binding.context.getPlural(R.plurals.fmt_album_count, artist.albums.size)
|
||||
}
|
||||
binding.context.getString(
|
||||
R.string.fmt_two,
|
||||
binding.context.getPlural(R.plurals.fmt_album_count, artist.albums.size),
|
||||
if (artist.songs.isNotEmpty()) {
|
||||
binding.context.getPlural(R.plurals.fmt_song_count, artist.songs.size)
|
||||
} else {
|
||||
binding.context.getString(R.string.def_song_count)
|
||||
})
|
||||
}
|
||||
|
||||
override fun updatePlayingIndicator(isActive: Boolean, isPlaying: Boolean) {
|
||||
|
@ -275,7 +274,11 @@ class PlaylistViewHolder private constructor(private val binding: ItemParentBind
|
|||
binding.parentImage.bind(playlist)
|
||||
binding.parentName.text = playlist.name.resolve(binding.context)
|
||||
binding.parentInfo.text =
|
||||
binding.context.getPlural(R.plurals.fmt_song_count, playlist.songs.size)
|
||||
if (playlist.songs.isNotEmpty()) {
|
||||
binding.context.getPlural(R.plurals.fmt_song_count, playlist.songs.size)
|
||||
} else {
|
||||
binding.context.getString(R.string.def_song_count)
|
||||
}
|
||||
}
|
||||
|
||||
override fun updatePlayingIndicator(isActive: Boolean, isPlaying: Boolean) {
|
||||
|
|
|
@ -326,6 +326,7 @@
|
|||
<string name="def_genre">Unknown genre</string>
|
||||
<string name="def_date">No date</string>
|
||||
<string name="def_track">No track</string>
|
||||
<string name="def_song_count">No songs</string>
|
||||
<string name="def_playback">No music playing</string>
|
||||
|
||||
<!-- Codec Namespace | Format names -->
|
||||
|
|
|
@ -62,6 +62,10 @@ open class FakeMusicRepository : MusicRepository {
|
|||
throw NotImplementedError()
|
||||
}
|
||||
|
||||
override fun addToPlaylist(songs: List<Song>, playlist: Playlist) {
|
||||
throw NotImplementedError()
|
||||
}
|
||||
|
||||
override fun requestIndex(withCache: Boolean) {
|
||||
throw NotImplementedError()
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ class MusicViewModelTest {
|
|||
TestMusicRepository().apply {
|
||||
indexingState = IndexingState.Indexing(IndexingProgress.Indeterminate)
|
||||
}
|
||||
val musicViewModel = MusicViewModel(indexer)
|
||||
val musicViewModel = MusicViewModel(indexer, FakeMusicSettings())
|
||||
assertTrue(indexer.updateListener is MusicViewModel)
|
||||
assertTrue(indexer.indexingListener is MusicViewModel)
|
||||
assertEquals(
|
||||
|
@ -47,7 +47,7 @@ class MusicViewModelTest {
|
|||
@Test
|
||||
fun statistics() {
|
||||
val musicRepository = TestMusicRepository()
|
||||
val musicViewModel = MusicViewModel(musicRepository)
|
||||
val musicViewModel = MusicViewModel(musicRepository, FakeMusicSettings())
|
||||
assertEquals(null, musicViewModel.statistics.value)
|
||||
musicRepository.deviceLibrary = TestDeviceLibrary()
|
||||
assertEquals(
|
||||
|
@ -64,7 +64,7 @@ class MusicViewModelTest {
|
|||
@Test
|
||||
fun requests() {
|
||||
val indexer = TestMusicRepository()
|
||||
val musicViewModel = MusicViewModel(indexer)
|
||||
val musicViewModel = MusicViewModel(indexer, FakeMusicSettings())
|
||||
musicViewModel.refresh()
|
||||
musicViewModel.rescan()
|
||||
assertEquals(listOf(true, false), indexer.requests)
|
||||
|
|
Loading…
Reference in a new issue