refactor: update image handling in Series dto to use imageUrlPrefix and JellyfinImageHelper

This commit is contained in:
2026-04-01 22:38:58 +02:00
parent ce5266f17c
commit 98850087ff
10 changed files with 25 additions and 21 deletions

View File

@@ -92,7 +92,7 @@ class SeriesScreenContentTest {
name = "Severance", name = "Severance",
synopsis = "Mark leads a team of office workers whose memories have been surgically divided.", synopsis = "Mark leads a team of office workers whose memories have been surgically divided.",
year = "2022", year = "2022",
heroImageUrl = "https://images.unsplash.com/photo-1500530855697-b586d89ba3ee", imageUrlPrefix = "https://images.unsplash.com/photo-1500530855697-b586d89ba3ee",
unwatchedEpisodeCount = 3, unwatchedEpisodeCount = 3,
seasonCount = 1, seasonCount = 1,
seasons = listOf( seasons = listOf(
@@ -154,7 +154,7 @@ class SeriesScreenContentTest {
name = "Foundation", name = "Foundation",
synopsis = "A band of exiles works to preserve knowledge through the fall of an empire.", synopsis = "A band of exiles works to preserve knowledge through the fall of an empire.",
year = "2021", year = "2021",
heroImageUrl = "https://images.unsplash.com/photo-1500530855697-b586d89ba3ee", imageUrlPrefix = "https://images.unsplash.com/photo-1500530855697-b586d89ba3ee",
unwatchedEpisodeCount = 0, unwatchedEpisodeCount = 0,
seasonCount = 1, seasonCount = 1,
seasons = listOf( seasons = listOf(

View File

@@ -18,11 +18,13 @@ import hu.bbara.purefin.common.ui.PurefinWaitingScreen
import hu.bbara.purefin.common.ui.components.MediaDetailOverviewSection import hu.bbara.purefin.common.ui.components.MediaDetailOverviewSection
import hu.bbara.purefin.common.ui.components.MediaDetailSectionTitle import hu.bbara.purefin.common.ui.components.MediaDetailSectionTitle
import hu.bbara.purefin.common.ui.components.TvMediaDetailScaffold import hu.bbara.purefin.common.ui.components.TvMediaDetailScaffold
import hu.bbara.purefin.core.data.image.JellyfinImageHelper
import hu.bbara.purefin.core.data.navigation.SeriesDto import hu.bbara.purefin.core.data.navigation.SeriesDto
import hu.bbara.purefin.core.model.Season import hu.bbara.purefin.core.model.Season
import hu.bbara.purefin.core.model.Series import hu.bbara.purefin.core.model.Series
import hu.bbara.purefin.feature.shared.content.series.SeriesViewModel import hu.bbara.purefin.feature.shared.content.series.SeriesViewModel
import org.jellyfin.sdk.model.UUID import org.jellyfin.sdk.model.UUID
import org.jellyfin.sdk.model.api.ImageType
@Composable @Composable
fun SeriesScreen( fun SeriesScreen(
@@ -78,7 +80,7 @@ internal fun SeriesScreenContent(
} }
TvMediaDetailScaffold( TvMediaDetailScaffold(
heroImageUrl = series.heroImageUrl, heroImageUrl = JellyfinImageHelper.finishImageUrl(series.imageUrlPrefix, ImageType.PRIMARY),
resetScrollKey = series.id, resetScrollKey = series.id,
modifier = modifier, modifier = modifier,
topBar = { topBar = {

View File

@@ -33,6 +33,7 @@ import androidx.hilt.navigation.compose.hiltViewModel
import hu.bbara.purefin.common.ui.MediaSynopsis import hu.bbara.purefin.common.ui.MediaSynopsis
import hu.bbara.purefin.common.ui.PurefinWaitingScreen import hu.bbara.purefin.common.ui.PurefinWaitingScreen
import hu.bbara.purefin.common.ui.components.MediaHero import hu.bbara.purefin.common.ui.components.MediaHero
import hu.bbara.purefin.core.data.image.JellyfinImageHelper
import hu.bbara.purefin.core.data.navigation.SeriesDto import hu.bbara.purefin.core.data.navigation.SeriesDto
import hu.bbara.purefin.core.model.CastMember import hu.bbara.purefin.core.model.CastMember
import hu.bbara.purefin.core.model.Episode import hu.bbara.purefin.core.model.Episode
@@ -41,6 +42,7 @@ import hu.bbara.purefin.core.model.Series
import hu.bbara.purefin.feature.download.DownloadState import hu.bbara.purefin.feature.download.DownloadState
import hu.bbara.purefin.feature.shared.content.series.SeriesViewModel import hu.bbara.purefin.feature.shared.content.series.SeriesViewModel
import hu.bbara.purefin.ui.theme.AppTheme import hu.bbara.purefin.ui.theme.AppTheme
import org.jellyfin.sdk.model.api.ImageType
import java.util.UUID import java.util.UUID
@Composable @Composable
@@ -198,7 +200,7 @@ private fun SeriesHeroSection(
.height(sectionHeight) .height(sectionHeight)
) { ) {
MediaHero( MediaHero(
imageUrl = series.heroImageUrl, imageUrl = JellyfinImageHelper.finishImageUrl(series.imageUrlPrefix, ImageType.PRIMARY),
backgroundColor = scheme.background, backgroundColor = scheme.background,
modifier = Modifier.fillMaxSize() modifier = Modifier.fillMaxSize()
) )
@@ -315,7 +317,7 @@ private fun previewSeries(): Series {
name = "Constellation", name = "Constellation",
synopsis = "When an experiment in orbit goes wrong, the survivors return home to a world that no longer fits their memories.", synopsis = "When an experiment in orbit goes wrong, the survivors return home to a world that no longer fits their memories.",
year = "2024", year = "2024",
heroImageUrl = "https://images.unsplash.com/photo-1446776811953-b23d57bd21aa", imageUrlPrefix = "https://images.unsplash.com/photo-1446776811953-b23d57bd21aa",
unwatchedEpisodeCount = 2, unwatchedEpisodeCount = 2,
seasonCount = 2, seasonCount = 2,
seasons = listOf( seasons = listOf(

View File

@@ -451,10 +451,9 @@ class InMemoryAppContentRepository @Inject constructor(
synopsis = this.overview ?: "No synopsis available", synopsis = this.overview ?: "No synopsis available",
year = this.productionYear?.toString() year = this.productionYear?.toString()
?: this.premiereDate?.year?.toString().orEmpty(), ?: this.premiereDate?.year?.toString().orEmpty(),
heroImageUrl = JellyfinImageHelper.toImageUrl( imageUrlPrefix = JellyfinImageHelper.toPrefixImageUrl(
url = serverUrl, url = serverUrl,
itemId = this.id, itemId = this.id
type = ImageType.PRIMARY
), ),
unwatchedEpisodeCount = this.userData!!.unplayedItemCount!!, unwatchedEpisodeCount = this.userData!!.unplayedItemCount!!,
seasonCount = this.childCount!!, seasonCount = this.childCount!!,

View File

@@ -1,7 +1,6 @@
package hu.bbara.purefin.core.data.room.entity package hu.bbara.purefin.core.data.room.entity
import androidx.room.Entity import androidx.room.Entity
import androidx.room.ForeignKey
import androidx.room.Index import androidx.room.Index
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import java.util.UUID import java.util.UUID
@@ -16,7 +15,7 @@ data class SeriesEntity(
val name: String, val name: String,
val synopsis: String, val synopsis: String,
val year: String, val year: String,
val heroImageUrl: String, val imageUrlPrefix: String,
val unwatchedEpisodeCount: Int, val unwatchedEpisodeCount: Int,
val seasonCount: Int val seasonCount: Int
) )

View File

@@ -23,7 +23,7 @@ import hu.bbara.purefin.core.data.room.entity.SmartDownloadEntity
EpisodeEntity::class, EpisodeEntity::class,
SmartDownloadEntity::class, SmartDownloadEntity::class,
], ],
version = 7, version = 8,
exportSchema = false exportSchema = false
) )
@TypeConverters(UuidConverters::class) @TypeConverters(UuidConverters::class)
@@ -33,4 +33,4 @@ abstract class OfflineMediaDatabase : RoomDatabase() {
abstract fun seasonDao(): SeasonDao abstract fun seasonDao(): SeasonDao
abstract fun episodeDao(): EpisodeDao abstract fun episodeDao(): EpisodeDao
abstract fun smartDownloadDao(): SmartDownloadDao abstract fun smartDownloadDao(): SmartDownloadDao
} }

View File

@@ -219,7 +219,7 @@ class OfflineRoomMediaLocalDataSource(
name = name, name = name,
synopsis = synopsis, synopsis = synopsis,
year = year, year = year,
heroImageUrl = heroImageUrl, imageUrlPrefix = imageUrlPrefix,
unwatchedEpisodeCount = unwatchedEpisodeCount, unwatchedEpisodeCount = unwatchedEpisodeCount,
seasonCount = seasonCount seasonCount = seasonCount
) )
@@ -272,7 +272,7 @@ class OfflineRoomMediaLocalDataSource(
name = name, name = name,
synopsis = synopsis, synopsis = synopsis,
year = year, year = year,
heroImageUrl = heroImageUrl, imageUrlPrefix = imageUrlPrefix,
unwatchedEpisodeCount = unwatchedEpisodeCount, unwatchedEpisodeCount = unwatchedEpisodeCount,
seasonCount = seasonCount, seasonCount = seasonCount,
seasons = seasons, seasons = seasons,
@@ -305,4 +305,4 @@ class OfflineRoomMediaLocalDataSource(
heroImageUrl = heroImageUrl, heroImageUrl = heroImageUrl,
cast = emptyList() cast = emptyList()
) )
} }

View File

@@ -8,7 +8,7 @@ data class Series(
val name: String, val name: String,
val synopsis: String, val synopsis: String,
val year: String, val year: String,
val heroImageUrl: String, val imageUrlPrefix: String,
val unwatchedEpisodeCount: Int, val unwatchedEpisodeCount: Int,
val seasonCount: Int, val seasonCount: Int,
val seasons: List<Season>, val seasons: List<Season>,

View File

@@ -385,10 +385,9 @@ class MediaDownloadManager @Inject constructor(
name = name ?: "Unknown", name = name ?: "Unknown",
synopsis = overview ?: "No synopsis available", synopsis = overview ?: "No synopsis available",
year = productionYear?.toString() ?: premiereDate?.year?.toString().orEmpty(), year = productionYear?.toString() ?: premiereDate?.year?.toString().orEmpty(),
heroImageUrl = JellyfinImageHelper.toImageUrl( imageUrlPrefix = JellyfinImageHelper.toPrefixImageUrl(
url = serverUrl, url = serverUrl,
itemId = id, itemId = id
type = ImageType.PRIMARY
), ),
unwatchedEpisodeCount = userData?.unplayedItemCount ?: 0, unwatchedEpisodeCount = userData?.unplayedItemCount ?: 0,
seasonCount = childCount ?: 0, seasonCount = childCount ?: 0,

View File

@@ -58,7 +58,10 @@ data class SuggestedSeries (
override val id: UUID = series.id, override val id: UUID = series.id,
override val title: String = series.name, override val title: String = series.name,
override val description: String = series.synopsis, override val description: String = series.synopsis,
override val imageUrl: String = series.heroImageUrl override val imageUrl: String = JellyfinImageHelper.finishImageUrl(
prefixImageUrl = series.imageUrlPrefix,
imageType = ImageType.PRIMARY
)
) : SuggestedItem ) : SuggestedItem
data class SuggestedMovie ( data class SuggestedMovie (
@@ -146,7 +149,7 @@ data class PosterItem(
val imageUrl: String = when (type) { val imageUrl: String = when (type) {
BaseItemKind.MOVIE -> movie!!.imageUrlPrefix BaseItemKind.MOVIE -> movie!!.imageUrlPrefix
BaseItemKind.EPISODE -> episode!!.heroImageUrl BaseItemKind.EPISODE -> episode!!.heroImageUrl
BaseItemKind.SERIES -> series!!.heroImageUrl BaseItemKind.SERIES -> series!!.imageUrlPrefix
else -> throw IllegalArgumentException("Invalid type: $type") else -> throw IllegalArgumentException("Invalid type: $type")
} }
fun watched() = when (type) { fun watched() = when (type) {