ui: fix click/menu issues

Fix some issues with how slapshod the menu/click code is.

This fixes a crash on the genre view when a song menu was opened.
This commit is contained in:
Alexander Capehart 2022-09-06 22:39:48 -06:00
parent 48ad45e4c3
commit fe5609b447
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
10 changed files with 45 additions and 62 deletions

View file

@ -9,6 +9,7 @@
- Fixed issue where the scroll popup would not display correctly in landscape mode [#230] - Fixed issue where the scroll popup would not display correctly in landscape mode [#230]
- Fixed issue where the playback progress would continue in the notification even if - Fixed issue where the playback progress would continue in the notification even if
audio focus was lost audio focus was lost
- Fixed issue where the app would crash if a song in the genre menu was opened
#### Dev/Meta #### Dev/Meta
- Completed migration to reactive playback system - Completed migration to reactive playback system

View file

@ -120,7 +120,7 @@ class AlbumDetailFragment :
} }
override fun onItemClick(item: Item) { override fun onItemClick(item: Item) {
if (item is Song) { check(item is Song) { "Unexpected datatype: ${item::class.simpleName}" }
val playbackMode = settings.detailPlaybackMode val playbackMode = settings.detailPlaybackMode
if (playbackMode != null) { if (playbackMode != null) {
playbackModel.play(item, playbackMode) playbackModel.play(item, playbackMode)
@ -128,15 +128,10 @@ class AlbumDetailFragment :
playbackModel.playFromAlbum(item) playbackModel.playFromAlbum(item)
} }
} }
}
override fun onOpenMenu(item: Item, anchor: View) { override fun onOpenMenu(item: Item, anchor: View) {
if (item is Song) { check(item is Song) { "Unexpected datatype: ${item::class.simpleName}" }
musicMenu(anchor, R.menu.menu_album_song_actions, item) musicMenu(anchor, R.menu.menu_album_song_actions, item)
return
}
error("Unexpected datatype when opening menu: ${item::class.java}")
} }
override fun onPlayParent() { override fun onPlayParent() {
@ -219,7 +214,7 @@ class AlbumDetailFragment :
.navigate(AlbumDetailFragmentDirections.actionShowArtist(item.uid)) .navigate(AlbumDetailFragmentDirections.actionShowArtist(item.uid))
} }
null -> {} null -> {}
else -> error("Unexpected navigation item ${item::class.java}") else -> error("Unexpected datatype: ${item::class.java}")
} }
} }

View file

@ -111,7 +111,6 @@ class ArtistDetailFragment :
} }
override fun onItemClick(item: Item) { override fun onItemClick(item: Item) {
when (item) { when (item) {
is Song -> { is Song -> {
val playbackMode = settings.detailPlaybackMode val playbackMode = settings.detailPlaybackMode
@ -122,6 +121,7 @@ class ArtistDetailFragment :
} }
} }
is Album -> navModel.exploreNavigateTo(item) is Album -> navModel.exploreNavigateTo(item)
else -> error("Unexpected datatype: ${item::class.simpleName}")
} }
} }
@ -129,7 +129,7 @@ class ArtistDetailFragment :
when (item) { when (item) {
is Song -> musicMenu(anchor, R.menu.menu_artist_song_actions, item) is Song -> musicMenu(anchor, R.menu.menu_artist_song_actions, item)
is Album -> musicMenu(anchor, R.menu.menu_artist_album_actions, item) is Album -> musicMenu(anchor, R.menu.menu_artist_album_actions, item)
else -> error("Unexpected datatype when opening menu: ${item::class.java}") else -> error("Unexpected datatype: ${item::class.simpleName}")
} }
} }
@ -196,7 +196,7 @@ class ArtistDetailFragment :
} }
} }
null -> {} null -> {}
else -> error("Unexpected navigation item ${item::class.java}") else -> error("Unexpected datatype: ${item::class.java}")
} }
} }

View file

@ -112,8 +112,7 @@ class GenreDetailFragment :
} }
override fun onItemClick(item: Item) { override fun onItemClick(item: Item) {
check(item is Song) check(item is Song) { "Unexpected datatype: ${item::class.simpleName}" }
val playbackMode = settings.detailPlaybackMode val playbackMode = settings.detailPlaybackMode
if (playbackMode != null) { if (playbackMode != null) {
playbackModel.play(item, playbackMode) playbackModel.play(item, playbackMode)
@ -123,12 +122,8 @@ class GenreDetailFragment :
} }
override fun onOpenMenu(item: Item, anchor: View) { override fun onOpenMenu(item: Item, anchor: View) {
if (item is Song) { check(item is Song) { "Unexpected datatype: ${item::class.simpleName}" }
musicMenu(anchor, R.menu.menu_song_actions, item) musicMenu(anchor, R.menu.menu_song_actions, item)
return
}
error("Unexpected datatype when opening menu: ${item::class.java}")
} }
override fun onPlayParent() { override fun onPlayParent() {

View file

@ -25,7 +25,6 @@ import java.util.*
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.music.Album import org.oxycblt.auxio.music.Album
import org.oxycblt.auxio.music.Music
import org.oxycblt.auxio.music.MusicParent import org.oxycblt.auxio.music.MusicParent
import org.oxycblt.auxio.ui.DisplayMode import org.oxycblt.auxio.ui.DisplayMode
import org.oxycblt.auxio.ui.Sort import org.oxycblt.auxio.ui.Sort
@ -98,15 +97,13 @@ class AlbumListFragment : HomeListFragment<Album>() {
} }
override fun onItemClick(item: Item) { override fun onItemClick(item: Item) {
check(item is Music) check(item is Album) { "Unexpected datatype: ${item::class.java}" }
navModel.exploreNavigateTo(item) navModel.exploreNavigateTo(item)
} }
override fun onOpenMenu(item: Item, anchor: View) { override fun onOpenMenu(item: Item, anchor: View) {
when (item) { check(item is Album) { "Unexpected datatype: ${item::class.java}" }
is Album -> musicMenu(anchor, R.menu.menu_album_actions, item) musicMenu(anchor, R.menu.menu_album_actions, item)
else -> error("Unexpected datatype when opening menu: ${item::class.java}")
}
} }
private fun handleParent(parent: MusicParent?, isPlaying: Boolean) { private fun handleParent(parent: MusicParent?, isPlaying: Boolean) {

View file

@ -23,7 +23,6 @@ import android.view.ViewGroup
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.music.Artist import org.oxycblt.auxio.music.Artist
import org.oxycblt.auxio.music.Music
import org.oxycblt.auxio.music.MusicParent import org.oxycblt.auxio.music.MusicParent
import org.oxycblt.auxio.ui.DisplayMode import org.oxycblt.auxio.ui.DisplayMode
import org.oxycblt.auxio.ui.Sort import org.oxycblt.auxio.ui.Sort
@ -74,17 +73,13 @@ class ArtistListFragment : HomeListFragment<Artist>() {
} }
override fun onItemClick(item: Item) { override fun onItemClick(item: Item) {
check(item is Music) check(item is Artist) { "Unexpected datatype: ${item::class.java}" }
navModel.exploreNavigateTo(item) navModel.exploreNavigateTo(item)
} }
override fun onOpenMenu(item: Item, anchor: View) { override fun onOpenMenu(item: Item, anchor: View) {
if (item is Artist) { check(item is Artist) { "Unexpected datatype: ${item::class.java}" }
musicMenu(anchor, R.menu.menu_genre_artist_actions, item) musicMenu(anchor, R.menu.menu_genre_artist_actions, item)
return
}
error("Unexpected datatype when opening menu: ${item::class.java}")
} }
private fun handleParent(parent: MusicParent?, isPlaying: Boolean) { private fun handleParent(parent: MusicParent?, isPlaying: Boolean) {

View file

@ -23,7 +23,6 @@ import android.view.ViewGroup
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.music.Genre import org.oxycblt.auxio.music.Genre
import org.oxycblt.auxio.music.Music
import org.oxycblt.auxio.music.MusicParent import org.oxycblt.auxio.music.MusicParent
import org.oxycblt.auxio.ui.DisplayMode import org.oxycblt.auxio.ui.DisplayMode
import org.oxycblt.auxio.ui.Sort import org.oxycblt.auxio.ui.Sort
@ -74,15 +73,13 @@ class GenreListFragment : HomeListFragment<Genre>() {
} }
override fun onItemClick(item: Item) { override fun onItemClick(item: Item) {
check(item is Music) check(item is Genre) { "Unexpected datatype: ${item::class.java}" }
navModel.exploreNavigateTo(item) navModel.exploreNavigateTo(item)
} }
override fun onOpenMenu(item: Item, anchor: View) { override fun onOpenMenu(item: Item, anchor: View) {
when (item) { check(item is Genre) { "Unexpected datatype: ${item::class.java}" }
is Genre -> musicMenu(anchor, R.menu.menu_genre_artist_actions, item) musicMenu(anchor, R.menu.menu_genre_artist_actions, item)
else -> error("Unexpected datatype when opening menu: ${item::class.java}")
}
} }
private fun handlePlayback(parent: MusicParent?, isPlaying: Boolean) { private fun handlePlayback(parent: MusicParent?, isPlaying: Boolean) {

View file

@ -103,15 +103,13 @@ class SongListFragment : HomeListFragment<Song>() {
} }
override fun onItemClick(item: Item) { override fun onItemClick(item: Item) {
check(item is Song) check(item is Song) { "Unexpected datatype: ${item::class.java}" }
playbackModel.play(item, settings.libPlaybackMode) playbackModel.play(item, settings.libPlaybackMode)
} }
override fun onOpenMenu(item: Item, anchor: View) { override fun onOpenMenu(item: Item, anchor: View) {
when (item) { check(item is Song) { "Unexpected datatype: ${item::class.java}" }
is Song -> musicMenu(anchor, R.menu.menu_song_actions, item) musicMenu(anchor, R.menu.menu_song_actions, item)
else -> error("Unexpected datatype when opening menu: ${item::class.java}")
}
} }
private fun handlePlayback(song: Song?, parent: MusicParent?, isPlaying: Boolean) { private fun handlePlayback(song: Song?, parent: MusicParent?, isPlaying: Boolean) {

View file

@ -71,7 +71,18 @@ sealed class Music : Item {
override fun equals(other: Any?) = override fun equals(other: Any?) =
other is Music && javaClass == other.javaClass && uid == other.uid other is Music && javaClass == other.javaClass && uid == other.uid
/** A unique identifier for a piece of music. */ /**
* A unique identifier for a piece of music.
*
* UID enables a much cheaper and more reliable form of differentiating music, derived from
* either a hash of meaningful metadata or the MusicBrainz UUID spec. It is the default datatype
* used when comparing music, and it is also the datatype used when serializing music to
* external sources.
*
* TODO: Verify hash mechanism works
*
* @author OxygenCobalt
*/
@Parcelize @Parcelize
class UID class UID
private constructor(val datatype: String, val isMusicBrainz: Boolean, val uuid: UUID) : private constructor(val datatype: String, val isMusicBrainz: Boolean, val uuid: UUID) :
@ -134,6 +145,7 @@ sealed class Music : Item {
val digest = MessageDigest.getInstance("MD5") val digest = MessageDigest.getInstance("MD5")
updates(digest) updates(digest)
// Make the MD5 hash and then bitshift it into a UUID.
val hash = digest.digest() val hash = digest.digest()
val uuid = val uuid =
UUID( UUID(

View file

@ -37,11 +37,7 @@ abstract class IndicatorAdapter<VH : RecyclerView.ViewHolder> : RecyclerView.Ada
if (holder is ViewHolder) { if (holder is ViewHolder) {
val item = currentList[position] val item = currentList[position]
val currentItem = currentItem val currentItem = currentItem
holder.updateIndicator( holder.updateIndicator(item == currentItem, isPlaying)
currentItem != null &&
item.javaClass == currentItem.javaClass &&
item == currentItem,
isPlaying)
} }
} }
@ -55,10 +51,7 @@ abstract class IndicatorAdapter<VH : RecyclerView.ViewHolder> : RecyclerView.Ada
currentItem = item currentItem = item
if (oldItem != null) { if (oldItem != null) {
val pos = val pos = currentList.indexOfFirst { it == oldItem }
currentList.indexOfFirst {
it.javaClass == oldItem.javaClass && item == currentItem
}
if (pos > -1) { if (pos > -1) {
notifyItemChanged(pos, PAYLOAD_INDICATOR_CHANGED) notifyItemChanged(pos, PAYLOAD_INDICATOR_CHANGED)
@ -68,7 +61,7 @@ abstract class IndicatorAdapter<VH : RecyclerView.ViewHolder> : RecyclerView.Ada
} }
if (item != null) { if (item != null) {
val pos = currentList.indexOfFirst { it.javaClass == item.javaClass && it == item } val pos = currentList.indexOfFirst { it == item }
if (pos > -1) { if (pos > -1) {
notifyItemChanged(pos, PAYLOAD_INDICATOR_CHANGED) notifyItemChanged(pos, PAYLOAD_INDICATOR_CHANGED)
@ -84,7 +77,7 @@ abstract class IndicatorAdapter<VH : RecyclerView.ViewHolder> : RecyclerView.Ada
this.isPlaying = isPlaying this.isPlaying = isPlaying
if (!updatedItem && item != null) { if (!updatedItem && item != null) {
val pos = currentList.indexOfFirst { it.javaClass == item.javaClass && it == item } val pos = currentList.indexOfFirst { it == item }
if (pos > -1) { if (pos > -1) {
notifyItemChanged(pos, PAYLOAD_INDICATOR_CHANGED) notifyItemChanged(pos, PAYLOAD_INDICATOR_CHANGED)