Twelve: Fix now playing artwork flashes

Wait for the player to go out of buffering

Change-Id: Iff41278ed15d896c720f4eeac874efc3d009a2cc
diff --git a/app/src/main/java/org/lineageos/twelve/fragments/NowPlayingFragment.kt b/app/src/main/java/org/lineageos/twelve/fragments/NowPlayingFragment.kt
index f6d08e0..092eb6b 100644
--- a/app/src/main/java/org/lineageos/twelve/fragments/NowPlayingFragment.kt
+++ b/app/src/main/java/org/lineageos/twelve/fragments/NowPlayingFragment.kt
@@ -7,7 +7,6 @@
 
 import android.animation.ValueAnimator
 import android.content.Intent
-import android.graphics.BitmapFactory
 import android.graphics.ImageDecoder
 import android.icu.text.DecimalFormat
 import android.icu.text.DecimalFormatSymbols
@@ -44,6 +43,7 @@
 import org.lineageos.twelve.ext.getViewProperty
 import org.lineageos.twelve.models.PlaybackState
 import org.lineageos.twelve.models.RepeatMode
+import org.lineageos.twelve.models.RequestStatus
 import org.lineageos.twelve.utils.TimestampFormatter
 import org.lineageos.twelve.viewmodels.NowPlayingViewModel
 import java.util.Locale
@@ -218,23 +218,6 @@
 
                 launch {
                     viewModel.mediaMetadata.collectLatest { mediaMetadata ->
-                        mediaMetadata.artworkData?.also { artworkData ->
-                            BitmapFactory.decodeByteArray(
-                                artworkData, 0, artworkData.size
-                            )?.let { bitmap ->
-                                albumArtImageView.setImageBitmap(bitmap)
-                            }
-                        } ?: mediaMetadata.artworkUri?.also { artworkUri ->
-                            ImageDecoder.createSource(
-                                requireContext().contentResolver,
-                                artworkUri
-                            ).let { source ->
-                                ImageDecoder.decodeBitmap(source)
-                            }.also { bitmap ->
-                                albumArtImageView.setImageBitmap(bitmap)
-                            }
-                        } ?: albumArtImageView.setImageResource(R.drawable.ic_music_note)
-
                         val audioTitle = mediaMetadata.displayTitle
                             ?: mediaMetadata.title
                         audioTitle?.let { title ->
@@ -267,6 +250,35 @@
                 }
 
                 launch {
+                    viewModel.mediaArtwork.collectLatest {
+                        when (it) {
+                            is RequestStatus.Loading -> {
+                                // Do nothing
+                            }
+
+                            is RequestStatus.Success -> {
+                                it.data?.bitmap?.also { bitmap ->
+                                    albumArtImageView.setImageBitmap(bitmap)
+                                } ?: it.data?.uri?.also { artworkUri ->
+                                    ImageDecoder.createSource(
+                                        requireContext().contentResolver,
+                                        artworkUri
+                                    ).let { source ->
+                                        ImageDecoder.decodeBitmap(source)
+                                    }.also { bitmap ->
+                                        albumArtImageView.setImageBitmap(bitmap)
+                                    }
+                                } ?: albumArtImageView.setImageResource(R.drawable.ic_music_note)
+                            }
+
+                            is RequestStatus.Error -> throw Exception(
+                                "Error while getting media artwork"
+                            )
+                        }
+                    }
+                }
+
+                launch {
                     viewModel.playbackParameters.collectLatest {
                         it?.also {
                             playbackSpeedMaterialButton.text = getString(
diff --git a/app/src/main/java/org/lineageos/twelve/viewmodels/NowPlayingViewModel.kt b/app/src/main/java/org/lineageos/twelve/viewmodels/NowPlayingViewModel.kt
index fd3ae41..b91b54a 100644
--- a/app/src/main/java/org/lineageos/twelve/viewmodels/NowPlayingViewModel.kt
+++ b/app/src/main/java/org/lineageos/twelve/viewmodels/NowPlayingViewModel.kt
@@ -6,6 +6,7 @@
 package org.lineageos.twelve.viewmodels
 
 import android.app.Application
+import android.graphics.BitmapFactory
 import androidx.lifecycle.viewModelScope
 import androidx.media3.common.C
 import androidx.media3.common.MediaMetadata
@@ -33,7 +34,10 @@
 import org.lineageos.twelve.ext.shuffleModeFlow
 import org.lineageos.twelve.ext.tracksFlow
 import org.lineageos.twelve.ext.typedRepeatMode
+import org.lineageos.twelve.models.PlaybackState
 import org.lineageos.twelve.models.RepeatMode
+import org.lineageos.twelve.models.RequestStatus
+import org.lineageos.twelve.models.Thumbnail
 
 open class NowPlayingViewModel(application: Application) : TwelveViewModel(application) {
     enum class PlaybackSpeed(val value: Float) {
@@ -126,6 +130,29 @@
             initialValue = null
         )
 
+    val mediaArtwork = combine(
+        mediaMetadata,
+        playbackState,
+    ) { mediaMetadata, playbackState ->
+        when (playbackState) {
+            PlaybackState.BUFFERING -> RequestStatus.Loading()
+
+            else -> RequestStatus.Success(
+                mediaMetadata.artworkUri?.let {
+                    Thumbnail(uri = it)
+                } ?: mediaMetadata.artworkData?.let {
+                    Thumbnail(bitmap = BitmapFactory.decodeByteArray(it, 0, it.size))
+                }
+            )
+        }
+    }
+        .flowOn(Dispatchers.IO)
+        .stateIn(
+            viewModelScope,
+            started = SharingStarted.WhileSubscribed(),
+            initialValue = RequestStatus.Loading()
+        )
+
     @androidx.annotation.OptIn(UnstableApi::class)
     @OptIn(ExperimentalCoroutinesApi::class)
     val currentTrackFormat = mediaController