diff --git a/app/src/main/java/org/oxycblt/auxio/detail/AlbumDetailFragment.kt b/app/src/main/java/org/oxycblt/auxio/detail/AlbumDetailFragment.kt index 9136e7232..56ebde771 100644 --- a/app/src/main/java/org/oxycblt/auxio/detail/AlbumDetailFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/detail/AlbumDetailFragment.kt @@ -134,7 +134,7 @@ class AlbumDetailFragment : DetailFragment() { playbackModel.song.observe(viewLifecycleOwner) { song -> if (playbackModel.mode.value == PlaybackMode.IN_ALBUM && - playbackModel.parent.value!!.id == detailModel.currentAlbum.value!!.id + playbackModel.parent.value?.id == detailModel.currentAlbum.value!!.id ) { detailAdapter.setCurrentSong(song) diff --git a/app/src/main/java/org/oxycblt/auxio/detail/ArtistDetailFragment.kt b/app/src/main/java/org/oxycblt/auxio/detail/ArtistDetailFragment.kt index 31df71038..b7bd521c8 100644 --- a/app/src/main/java/org/oxycblt/auxio/detail/ArtistDetailFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/detail/ArtistDetailFragment.kt @@ -10,9 +10,12 @@ import androidx.navigation.fragment.navArgs import org.oxycblt.auxio.R import org.oxycblt.auxio.detail.adapters.ArtistDetailAdapter import org.oxycblt.auxio.logD +import org.oxycblt.auxio.music.Album import org.oxycblt.auxio.music.Artist import org.oxycblt.auxio.music.BaseModel import org.oxycblt.auxio.music.MusicStore +import org.oxycblt.auxio.playback.state.PlaybackMode +import org.oxycblt.auxio.recycler.Highlightable import org.oxycblt.auxio.ui.setupAlbumActions /** @@ -104,6 +107,39 @@ class ArtistDetailFragment : DetailFragment() { } } + // --- PLAYBACKVIEWMODEL SETUP --- + + playbackModel.parent.observe(viewLifecycleOwner) { parent -> + if (playbackModel.mode.value == PlaybackMode.IN_ALBUM && parent is Album?) { + detailAdapter.setCurrentAlbum(parent) + + lastHolder?.setHighlighted(false) + lastHolder = null + + if (parent != null) { + // Use existing data instead of having to re-sort it. + val pos = detailAdapter.currentList.indexOfFirst { + it.name == parent.name + } + + // Check if the ViewHolder if this album is visible, and highlight it if so. + binding.detailRecycler.layoutManager?.findViewByPosition(pos)?.let { child -> + binding.detailRecycler.getChildViewHolder(child)?.let { + lastHolder = it as Highlightable + + lastHolder?.setHighlighted(true) + } + } + } + } else { + // Clear the viewholders if the mode isn't IN_ALBUM + detailAdapter.setCurrentAlbum(null) + + lastHolder?.setHighlighted(false) + lastHolder = null + } + } + logD("Fragment created.") return binding.root diff --git a/app/src/main/java/org/oxycblt/auxio/detail/adapters/ArtistDetailAdapter.kt b/app/src/main/java/org/oxycblt/auxio/detail/adapters/ArtistDetailAdapter.kt index fe1b49902..c398c9009 100644 --- a/app/src/main/java/org/oxycblt/auxio/detail/adapters/ArtistDetailAdapter.kt +++ b/app/src/main/java/org/oxycblt/auxio/detail/adapters/ArtistDetailAdapter.kt @@ -13,8 +13,11 @@ import org.oxycblt.auxio.music.Album import org.oxycblt.auxio.music.Artist import org.oxycblt.auxio.music.BaseModel import org.oxycblt.auxio.recycler.DiffCallback +import org.oxycblt.auxio.recycler.Highlightable import org.oxycblt.auxio.recycler.viewholders.BaseViewHolder +import org.oxycblt.auxio.ui.accent import org.oxycblt.auxio.ui.disable +import org.oxycblt.auxio.ui.setTextColorResource /** * An adapter for displaying the [Album]s of an artist. @@ -25,6 +28,8 @@ class ArtistDetailAdapter( private val doOnClick: (data: Album) -> Unit, private val doOnLongClick: (data: Album, view: View) -> Unit, ) : ListAdapter(DiffCallback()) { + private var currentAlbum: Album? = null + private var lastHolder: Highlightable? = null override fun getItemViewType(position: Int): Int { return when (getItem(position)) { @@ -54,6 +59,30 @@ class ArtistDetailAdapter( is Artist -> (holder as ArtistHeaderViewHolder).bind(item) is Album -> (holder as ArtistAlbumViewHolder).bind(item) } + + if (currentAlbum != null && position > 0) { + if (getItem(position).id == currentAlbum?.id) { + // Reset the last ViewHolder before assigning the new, correct one to be highlighted + lastHolder?.setHighlighted(false) + lastHolder = (holder as Highlightable) + holder.setHighlighted(true) + } else { + (holder as Highlightable).setHighlighted(false) + } + } + } + + /** + * Update the current album that this adapter should be watching for to highlight. + * @param album The [Album] to highlight if found, null to clear any highlighted ViewHolders + */ + fun setCurrentAlbum(album: Album?) { + // Clear out the last ViewHolder as a song update usually signifies that this current + // ViewHolder is likely invalid. + lastHolder?.setHighlighted(false) + lastHolder = null + + currentAlbum = album } inner class ArtistHeaderViewHolder( @@ -74,13 +103,22 @@ class ArtistDetailAdapter( // Generic ViewHolder for a detail album inner class ArtistAlbumViewHolder( private val binding: ItemArtistAlbumBinding, - ) : BaseViewHolder(binding, doOnClick, doOnLongClick) { + ) : BaseViewHolder(binding, doOnClick, doOnLongClick), Highlightable { + private val normalTextColor = binding.albumName.currentTextColor override fun onBind(data: Album) { binding.album = data binding.albumName.requestLayout() } + + override fun setHighlighted(isHighlighted: Boolean) { + if (isHighlighted) { + binding.albumName.setTextColorResource(accent.first) + } else { + binding.albumName.setTextColor(normalTextColor) + } + } } companion object { diff --git a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackService.kt b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackService.kt index 66876e777..8bf9bb837 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackService.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackService.kt @@ -438,9 +438,11 @@ class PlaybackService : Service(), Player.EventListener, PlaybackStateManager.Ca * @param reason (Debug) The reason for this call. */ private fun startForegroundOrNotify(reason: String) { - // Don't start the foreground if the playback hasn't started yet AND if the playback hasn't - // been restored - if (playbackManager.hasPlayed && playbackManager.isRestored) { + // Don't start the foreground if: + // - The playback hasnt even started + // - The playback hasnt been restored + // - There is nothing to play + if (playbackManager.hasPlayed && playbackManager.isRestored && playbackManager.song != null) { logD("Starting foreground/notifying because of $reason") if (!isForeground) { diff --git a/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt b/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt index c65962223..aa8796a1e 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt @@ -368,6 +368,7 @@ class PlaybackStateManager private constructor() { forceQueueUpdate() mSong = null + mParent = null } } }