diff --git a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackPanelFragment.kt b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackPanelFragment.kt index c73a1b814..b6b2b5bae 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackPanelFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackPanelFragment.kt @@ -24,6 +24,7 @@ import android.media.audiofx.AudioEffect import android.os.Bundle import android.view.LayoutInflater import android.view.MenuItem +import android.view.ViewTreeObserver import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.contract.ActivityResultContracts import androidx.appcompat.widget.Toolbar @@ -59,11 +60,13 @@ class PlaybackPanelFragment : ViewBindingFragment(), Toolbar.OnMenuItemClickListener, StyledSeekBar.Listener, - SwipeCoverView.OnSwipeListener { + SwipeCoverView.OnSwipeListener, + ViewTreeObserver.OnGlobalLayoutListener { private val playbackModel: PlaybackViewModel by activityViewModels() private val detailModel: DetailViewModel by activityViewModels() private val listModel: ListViewModel by activityViewModels() private var equalizerLauncher: ActivityResultLauncher? = null + private var lastCoverWidth = 0 override fun onCreateBinding(inflater: LayoutInflater) = FragmentPlaybackPanelBinding.inflate(inflater) @@ -131,6 +134,41 @@ class PlaybackPanelFragment : collectImmediately(playbackModel.isShuffled, ::updateShuffled) } + override fun onStart() { + super.onStart() + logD(requireBinding().playbackCover.width) + playbackModel.song.value?.let { requireBinding().playbackCover.bind(it) } + requireBinding().root.viewTreeObserver.addOnGlobalLayoutListener(this) + } + + override fun onStop() { + super.onStop() + requireBinding().root.viewTreeObserver.removeOnGlobalLayoutListener(this) + } + + override fun onGlobalLayout() { + if (binding == null || lastCoverWidth < 0) { + return + } + // Hacky workaround for cover radius not being preserved in between sizing changes + // (i.e split screen or landscape mode) + // For some reason ConstraintLayout does several passes on 1:1 elements that causes their + // size to radically change, so we wait until it stabilizes and then force an image + // reload if needed. Optimistically this is a no-op from coil caching, but when the cover + // did accidentally load the wrong image (with weird corner radius intended for bigger + // covers) we can force it to reload. + // If this breaks, it's fine since we also started a load as we normally did w/state + // updates, so the cover will not break. + val binding = requireBinding() + val coverWidth = binding.playbackCover.width + if (lastCoverWidth != coverWidth) { + lastCoverWidth = coverWidth + } else { + playbackModel.song.value?.let { binding.playbackCover.bind(it) } + lastCoverWidth = -1 + } + } + override fun onDestroyBinding(binding: FragmentPlaybackPanelBinding) { equalizerLauncher = null binding.playbackSong.isSelected = false