From 6ef1a105b84e6f46906d6a899a0eec48c6a50940 Mon Sep 17 00:00:00 2001 From: austinried <4966622+austinried@users.noreply.github.com> Date: Wed, 23 Sep 2026 16:39:33 +0000 Subject: [PATCH] crossfade cover art and show the thumbnail under the full image --- .../main/kotlin/com/subtracks/SubtracksApp.kt | 2 ++ .../com/subtracks/ui/components/Components.kt | 31 ++++++++++++++----- .../subtracks/ui/library/AlbumDetailScreen.kt | 1 + 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/app/src/main/kotlin/com/subtracks/SubtracksApp.kt b/app/src/main/kotlin/com/subtracks/SubtracksApp.kt index 54113249..b1113117 100644 --- a/app/src/main/kotlin/com/subtracks/SubtracksApp.kt +++ b/app/src/main/kotlin/com/subtracks/SubtracksApp.kt @@ -4,6 +4,7 @@ import android.app.Application import coil3.ImageLoader import coil3.SingletonImageLoader import coil3.network.okhttp.OkHttpNetworkFetcherFactory +import coil3.request.crossfade import com.subtracks.di.appModule import okhttp3.OkHttpClient import org.koin.core.context.startKoin @@ -22,6 +23,7 @@ class SubtracksApp : Application() { ImageLoader .Builder(context) .components { add(OkHttpNetworkFetcherFactory(callFactory = { http })) } + .crossfade(150) .build() } } diff --git a/app/src/main/kotlin/com/subtracks/ui/components/Components.kt b/app/src/main/kotlin/com/subtracks/ui/components/Components.kt index 422363e5..be602dab 100644 --- a/app/src/main/kotlin/com/subtracks/ui/components/Components.kt +++ b/app/src/main/kotlin/com/subtracks/ui/components/Components.kt @@ -1,5 +1,6 @@ package com.subtracks.ui.components +import android.content.Context import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize @@ -8,6 +9,7 @@ import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.layout.ContentScale @@ -23,7 +25,9 @@ fun CoverArt( ref: CoverArtRef?, name: String, modifier: Modifier = Modifier, + thumbnailRef: CoverArtRef? = null, ) { + val context = LocalPlatformContext.current Box(modifier = modifier.background(MaterialTheme.colorScheme.surfaceVariant)) { Text( text = name.trim().take(1).uppercase(), @@ -31,15 +35,17 @@ fun CoverArt( color = MaterialTheme.colorScheme.onSurfaceVariant, modifier = Modifier.align(Alignment.Center), ) + if (thumbnailRef != null && thumbnailRef != ref) { + AsyncImage( + model = remember(thumbnailRef) { imageRequest(context, thumbnailRef) }, + contentDescription = null, + contentScale = ContentScale.Crop, + modifier = Modifier.fillMaxSize(), + ) + } if (ref != null) { AsyncImage( - model = - ImageRequest - .Builder(LocalPlatformContext.current) - .data(ref.url) - .memoryCacheKey(ref.cacheKey) - .diskCacheKey(ref.cacheKey) - .build(), + model = remember(ref) { imageRequest(context, ref) }, contentDescription = null, contentScale = ContentScale.Crop, modifier = Modifier.fillMaxSize(), @@ -48,6 +54,17 @@ fun CoverArt( } } +private fun imageRequest( + context: Context, + ref: CoverArtRef, +): ImageRequest = + ImageRequest + .Builder(context) + .data(ref.url) + .memoryCacheKey(ref.cacheKey) + .diskCacheKey(ref.cacheKey) + .build() + @Composable fun LoadingState(modifier: Modifier = Modifier) { Box(modifier.fillMaxSize(), contentAlignment = Alignment.Center) { diff --git a/app/src/main/kotlin/com/subtracks/ui/library/AlbumDetailScreen.kt b/app/src/main/kotlin/com/subtracks/ui/library/AlbumDetailScreen.kt index d4168755..d803ec75 100644 --- a/app/src/main/kotlin/com/subtracks/ui/library/AlbumDetailScreen.kt +++ b/app/src/main/kotlin/com/subtracks/ui/library/AlbumDetailScreen.kt @@ -282,6 +282,7 @@ private fun AlbumHeader( CoverArt( ref = coverArt(album?.coverArt, false), name = album?.name.orEmpty(), + thumbnailRef = coverArt(album?.coverArt, true), modifier = Modifier .fillMaxWidth(0.86f)