From 9d638d5984b36e2e9bbcdfa9dd7ebb15ad7b5e18 Mon Sep 17 00:00:00 2001 From: leekleak <142348248+leekleak@users.noreply.github.com> Date: Tue, 11 Nov 2025 20:15:41 +0200 Subject: [PATCH] Fix album cover jank (#1658) * fix album cover jank * reduce album resolution --- .../ui/launcher/widgets/music/MusicWidget.kt | 16 +--------------- .../ui/launcher/widgets/music/MusicWidgetVM.kt | 3 ++- .../java/de/mm20/launcher2/music/MusicService.kt | 5 +++++ services/music/src/main/res/values/dimens.xml | 2 +- 4 files changed, 9 insertions(+), 17 deletions(-) diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/music/MusicWidget.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/music/MusicWidget.kt index 43eac73df..f1999cfc6 100644 --- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/music/MusicWidget.kt +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/music/MusicWidget.kt @@ -229,21 +229,7 @@ fun MusicWidget(widget: MusicWidget) { } } } - AnimatedContent( - albumArt, - transitionSpec = { - if (targetState != null && initialState == null) { - fadeIn() togetherWith fadeOut() - } else { - (fadeIn(animationSpec = tween(220, delayMillis = 90)) + - scaleIn( - initialScale = 0.92f, - animationSpec = tween(220, delayMillis = 90) - )) - .togetherWith(fadeOut(animationSpec = tween(90))) - } - } - ) { art -> + AnimatedContent(albumArt) { art -> Box( modifier = Modifier .padding(top = 16.dp, end = 16.dp) diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/music/MusicWidgetVM.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/music/MusicWidgetVM.kt index 39241e3f6..49df60d43 100644 --- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/music/MusicWidgetVM.kt +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/music/MusicWidgetVM.kt @@ -14,6 +14,7 @@ import de.mm20.launcher2.music.SupportedActions import de.mm20.launcher2.permissions.PermissionGroup import de.mm20.launcher2.permissions.PermissionsManager import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.debounce import org.koin.core.component.KoinComponent import org.koin.core.component.inject @@ -23,7 +24,7 @@ class MusicWidgetVM: ViewModel(), KoinComponent { val title: Flow = musicService.title val artist: Flow = musicService.artist - val albumArt: Flow = musicService.albumArt + val albumArt: Flow = musicService.albumArt.debounce { if (it == null) 500 else 0L } val playbackState: Flow = musicService.playbackState val duration: Flow = musicService.duration val position: Flow = musicService.position diff --git a/services/music/src/main/java/de/mm20/launcher2/music/MusicService.kt b/services/music/src/main/java/de/mm20/launcher2/music/MusicService.kt index fb67b3128..ecb780a01 100644 --- a/services/music/src/main/java/de/mm20/launcher2/music/MusicService.kt +++ b/services/music/src/main/java/de/mm20/launcher2/music/MusicService.kt @@ -320,6 +320,7 @@ internal class MusicServiceImpl( override val albumArt: Flow = channelFlow { val size = context.resources.getDimensionPixelSize(R.dimen.album_art_size) + var lastBitmap: Bitmap? = null currentMetadata.collectLatest { metadata -> if (metadata == null) { val isNull = preferences.getString(PREFS_KEY_ALBUM_ART, "null") == "null" @@ -345,6 +346,9 @@ internal class MusicServiceImpl( ?.let { loadBitmapFromUri(Uri.parse(it), size) } ?: metadata.getString(MediaMetadata.METADATA_KEY_ART_URI) ?.let { loadBitmapFromUri(Uri.parse(it), size) } + + if (lastBitmap != null && lastBitmap!!.sameAs(bitmap)) + return@collectLatest withContext(Dispatchers.IO) { if (bitmap == null) { preferences.edit { @@ -359,6 +363,7 @@ internal class MusicServiceImpl( } } send(bitmap) + lastBitmap = bitmap } }.shareIn(scope, SharingStarted.WhileSubscribed(), 1) diff --git a/services/music/src/main/res/values/dimens.xml b/services/music/src/main/res/values/dimens.xml index c8637f624..f1c7fcd3f 100644 --- a/services/music/src/main/res/values/dimens.xml +++ b/services/music/src/main/res/values/dimens.xml @@ -1,3 +1,3 @@ - 144dp + 96dp