From 7024a7975875d017ec15711848809dff7175a693 Mon Sep 17 00:00:00 2001 From: imashnake0 Date: Mon, 8 Jan 2024 08:54:19 -0500 Subject: [PATCH 1/4] Higher quality thumbnails --- .../api/anilist/sanitize/media/Media.kt | 24 ++++++++++++++-- .../animite/features/media/MediaPage.kt | 28 ++++++++++++++++--- 2 files changed, 46 insertions(+), 6 deletions(-) diff --git a/api/anilist/src/main/kotlin/com/imashnake/animite/api/anilist/sanitize/media/Media.kt b/api/anilist/src/main/kotlin/com/imashnake/animite/api/anilist/sanitize/media/Media.kt index ccb9ddf4..050ca5bd 100644 --- a/api/anilist/src/main/kotlin/com/imashnake/animite/api/anilist/sanitize/media/Media.kt +++ b/api/anilist/src/main/kotlin/com/imashnake/animite/api/anilist/sanitize/media/Media.kt @@ -5,6 +5,10 @@ import com.imashnake.animite.api.anilist.MediaListQuery import com.imashnake.animite.api.anilist.MediaQuery import com.imashnake.animite.api.anilist.type.MediaRankType +private const val HQ_DEFAULT = "hqdefault" +private const val MAX_RES_DEFAULT = "maxresdefault" +private const val SD_DEFAULT = "sddefault" + data class Media( /** @see MediaQuery.Media.bannerImage */ val bannerImage: String?, @@ -54,7 +58,7 @@ data class Media( * @see MediaQuery.Trailer.site */ val url: String?, /** @see MediaQuery.Trailer.thumbnail */ - val thumbnail: String?, + val thumbnail: Thumbnail, ) { /** @see MediaQuery.Trailer.thumbnail */ enum class Site(val baseUrl: String) { @@ -62,6 +66,12 @@ data class Media( DAILYMOTION("https://www.dailymotion.com/video/"), UNKNOWN("") } + + data class Thumbnail( + val maxResDefault: String?, + val sdDefault: String?, + val defaultThumbnail: String? + ) } internal constructor(query: MediaQuery.Media) : this( @@ -101,7 +111,17 @@ data class Media( } else { Trailer( url = "${Trailer.Site.valueOf(query.trailer.site.uppercase()).baseUrl}${query.trailer.id}", - thumbnail = query.trailer.thumbnail + thumbnail = with(query.trailer) { + Trailer.Thumbnail( + maxResDefault = thumbnail?.takeIf { + it.contains(HQ_DEFAULT) + }?.replace(HQ_DEFAULT, MAX_RES_DEFAULT), + sdDefault = thumbnail?.takeIf { + it.contains(HQ_DEFAULT) + }?.replace(HQ_DEFAULT, SD_DEFAULT), + defaultThumbnail = thumbnail + ) + } ) } ) diff --git a/app/src/main/java/com/imashnake/animite/features/media/MediaPage.kt b/app/src/main/java/com/imashnake/animite/features/media/MediaPage.kt index 83f2b692..b67fb477 100644 --- a/app/src/main/java/com/imashnake/animite/features/media/MediaPage.kt +++ b/app/src/main/java/com/imashnake/animite/features/media/MediaPage.kt @@ -43,7 +43,10 @@ import androidx.compose.material3.SuggestionChip import androidx.compose.material3.SuggestionChipDefaults import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -408,16 +411,33 @@ fun MediaTrailer( modifier = Modifier .wrapContentSize() .clip(RoundedCornerShape(dimensionResource(R.dimen.trailer_corner_radius))) + .background(color = MaterialTheme.colorScheme.primaryContainer.copy(alpha = 0.15f)) .clickable { val appIntent = Intent(Intent.ACTION_VIEW, Uri.parse(trailer.url)) context.startActivity(appIntent) } ) { + var bestThumbnail by remember { mutableStateOf(trailer.thumbnail.maxResDefault) } + + val model = ImageRequest.Builder(context) + .data(bestThumbnail) + .listener( + onError = { _, _ -> + bestThumbnail = trailer.thumbnail.sdDefault + } + ) + .data(bestThumbnail) + .listener( + onError = { _, _ -> + bestThumbnail = trailer.thumbnail.defaultThumbnail + } + ) + .data(bestThumbnail) + .crossfade(Constants.CROSSFADE_DURATION) + .build() + AsyncImage( - model = ImageRequest.Builder(LocalContext.current) - .data(trailer.thumbnail) - .crossfade(Constants.CROSSFADE_DURATION) - .build(), + model = model, contentDescription = stringResource(R.string.trailer), contentScale = ContentScale.FillWidth, modifier = Modifier From 111034197707fdf7b25e1c39e2f1e6a5758f158e Mon Sep 17 00:00:00 2001 From: imashnake0 Date: Tue, 9 Jan 2024 01:45:56 -0500 Subject: [PATCH 2/4] Conditional fallbacks Made fallbacks conditional so they don't always happen. --- .../animite/features/media/MediaPage.kt | 35 +++++++++++-------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/com/imashnake/animite/features/media/MediaPage.kt b/app/src/main/java/com/imashnake/animite/features/media/MediaPage.kt index b67fb477..a5780508 100644 --- a/app/src/main/java/com/imashnake/animite/features/media/MediaPage.kt +++ b/app/src/main/java/com/imashnake/animite/features/media/MediaPage.kt @@ -419,22 +419,27 @@ fun MediaTrailer( ) { var bestThumbnail by remember { mutableStateOf(trailer.thumbnail.maxResDefault) } - val model = ImageRequest.Builder(context) - .data(bestThumbnail) - .listener( - onError = { _, _ -> - bestThumbnail = trailer.thumbnail.sdDefault - } - ) - .data(bestThumbnail) - .listener( - onError = { _, _ -> - bestThumbnail = trailer.thumbnail.defaultThumbnail + val model = remember(bestThumbnail) { + ImageRequest.Builder(context) + .data(bestThumbnail) + .apply { + if (bestThumbnail?.contains("maxresdefault") == true) { + listener( + onError = { _, _ -> + bestThumbnail = trailer.thumbnail.sdDefault + } + ) + } else { + listener( + onError = { _, _ -> + bestThumbnail = trailer.thumbnail.defaultThumbnail + } + ) + } } - ) - .data(bestThumbnail) - .crossfade(Constants.CROSSFADE_DURATION) - .build() + .crossfade(Constants.CROSSFADE_DURATION) + .build() + } AsyncImage( model = model, From f65bac1647461e54e7c216b715b5d15985337b02 Mon Sep 17 00:00:00 2001 From: imashnake0 Date: Tue, 9 Jan 2024 01:54:11 -0500 Subject: [PATCH 3/4] Collapsed if-else --- .../animite/features/media/MediaPage.kt | 21 +++++++------------ 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/com/imashnake/animite/features/media/MediaPage.kt b/app/src/main/java/com/imashnake/animite/features/media/MediaPage.kt index a5780508..d5f6a28d 100644 --- a/app/src/main/java/com/imashnake/animite/features/media/MediaPage.kt +++ b/app/src/main/java/com/imashnake/animite/features/media/MediaPage.kt @@ -423,19 +423,14 @@ fun MediaTrailer( ImageRequest.Builder(context) .data(bestThumbnail) .apply { - if (bestThumbnail?.contains("maxresdefault") == true) { - listener( - onError = { _, _ -> - bestThumbnail = trailer.thumbnail.sdDefault - } - ) - } else { - listener( - onError = { _, _ -> - bestThumbnail = trailer.thumbnail.defaultThumbnail - } - ) - } + listener( + onError = { _, _ -> + bestThumbnail = if (bestThumbnail?.contains("maxresdefault") == true) { + trailer.thumbnail.sdDefault + } else trailer.thumbnail.defaultThumbnail + Log.d("bestThumbnail", bestThumbnail.toString()) + } + ) } .crossfade(Constants.CROSSFADE_DURATION) .build() From ddb8f9d63da1dd2a4c8d5a7d9532931626df0797 Mon Sep 17 00:00:00 2001 From: imashnake0 Date: Tue, 9 Jan 2024 09:23:05 -0500 Subject: [PATCH 4/4] Cleanup Co-Authored-By: Agung Watanabe <52477630+uragiristereo@users.noreply.github.com> --- .../java/com/imashnake/animite/features/media/MediaPage.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/imashnake/animite/features/media/MediaPage.kt b/app/src/main/java/com/imashnake/animite/features/media/MediaPage.kt index d5f6a28d..c6549f17 100644 --- a/app/src/main/java/com/imashnake/animite/features/media/MediaPage.kt +++ b/app/src/main/java/com/imashnake/animite/features/media/MediaPage.kt @@ -46,6 +46,7 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -417,7 +418,7 @@ fun MediaTrailer( context.startActivity(appIntent) } ) { - var bestThumbnail by remember { mutableStateOf(trailer.thumbnail.maxResDefault) } + var bestThumbnail by rememberSaveable { mutableStateOf(trailer.thumbnail.maxResDefault) } val model = remember(bestThumbnail) { ImageRequest.Builder(context) @@ -428,7 +429,6 @@ fun MediaTrailer( bestThumbnail = if (bestThumbnail?.contains("maxresdefault") == true) { trailer.thumbnail.sdDefault } else trailer.thumbnail.defaultThumbnail - Log.d("bestThumbnail", bestThumbnail.toString()) } ) }