diff --git a/app-tv/src/androidTest/java/hu/bbara/purefin/app/content/movie/MovieScreenContentTest.kt b/app-tv/src/androidTest/java/hu/bbara/purefin/app/content/movie/MovieScreenContentTest.kt index 3e30f4d4..aebbd8fb 100644 --- a/app-tv/src/androidTest/java/hu/bbara/purefin/app/content/movie/MovieScreenContentTest.kt +++ b/app-tv/src/androidTest/java/hu/bbara/purefin/app/content/movie/MovieScreenContentTest.kt @@ -65,7 +65,7 @@ class MovieScreenContentTest { runtime = "164m", format = "4K", synopsis = "Officer K uncovers a secret that sends him searching for Rick Deckard.", - heroImageUrl = "https://images.unsplash.com/photo-1500530855697-b586d89ba3ee", + imageUrlPrefix = "https://images.unsplash.com/photo-1500530855697-b586d89ba3ee", audioTrack = "ENG 5.1", subtitles = "ENG", cast = listOf( diff --git a/app-tv/src/main/java/hu/bbara/purefin/app/content/movie/MovieScreen.kt b/app-tv/src/main/java/hu/bbara/purefin/app/content/movie/MovieScreen.kt index d19c8953..78e669d4 100644 --- a/app-tv/src/main/java/hu/bbara/purefin/app/content/movie/MovieScreen.kt +++ b/app-tv/src/main/java/hu/bbara/purefin/app/content/movie/MovieScreen.kt @@ -19,9 +19,11 @@ import hu.bbara.purefin.common.ui.components.MediaDetailOverviewSection import hu.bbara.purefin.common.ui.components.MediaDetailPlaybackSection import hu.bbara.purefin.common.ui.components.MediaDetailSectionTitle import hu.bbara.purefin.common.ui.components.TvMediaDetailScaffold +import hu.bbara.purefin.core.data.image.JellyfinImageHelper import hu.bbara.purefin.core.data.navigation.MovieDto import hu.bbara.purefin.core.model.Movie import hu.bbara.purefin.feature.shared.content.movie.MovieScreenViewModel +import org.jellyfin.sdk.model.api.ImageType @Composable fun MovieScreen( @@ -60,7 +62,7 @@ internal fun MovieScreenContent( } TvMediaDetailScaffold( - heroImageUrl = movie.heroImageUrl, + heroImageUrl = JellyfinImageHelper.finishImageUrl(movie.imageUrlPrefix, ImageType.PRIMARY), resetScrollKey = movie.id, modifier = modifier, topBar = { diff --git a/app-tv/src/main/java/hu/bbara/purefin/tv/home/ui/TvHomeSections.kt b/app-tv/src/main/java/hu/bbara/purefin/tv/home/ui/TvHomeSections.kt index 3e44bff7..f7b567de 100644 --- a/app-tv/src/main/java/hu/bbara/purefin/tv/home/ui/TvHomeSections.kt +++ b/app-tv/src/main/java/hu/bbara/purefin/tv/home/ui/TvHomeSections.kt @@ -39,11 +39,13 @@ import androidx.compose.ui.unit.sp import hu.bbara.purefin.common.ui.PosterCard import hu.bbara.purefin.common.ui.components.MediaProgressBar import hu.bbara.purefin.common.ui.components.PurefinAsyncImage +import hu.bbara.purefin.core.data.image.JellyfinImageHelper import hu.bbara.purefin.feature.shared.home.ContinueWatchingItem import hu.bbara.purefin.feature.shared.home.NextUpItem import hu.bbara.purefin.feature.shared.home.PosterItem import org.jellyfin.sdk.model.UUID import org.jellyfin.sdk.model.api.BaseItemKind +import org.jellyfin.sdk.model.api.ImageType import kotlin.math.nextUp @Composable @@ -67,8 +69,6 @@ fun TvContinueWatchingSection( itemsIndexed(items = items) { index, item -> TvContinueWatchingCard( item = item, - isFirstItem = index == 0, - isLastItem = index == items.lastIndex, onMovieSelected = onMovieSelected, onEpisodeSelected = onEpisodeSelected ) @@ -80,8 +80,6 @@ fun TvContinueWatchingSection( fun TvContinueWatchingCard( item: ContinueWatchingItem, modifier: Modifier = Modifier, - isFirstItem: Boolean = false, - isLastItem: Boolean = false, onMovieSelected: (UUID) -> Unit, onEpisodeSelected: (UUID, UUID, UUID) -> Unit, ) { @@ -91,7 +89,10 @@ fun TvContinueWatchingCard( val scale by animateFloatAsState(targetValue = if (isFocused) 1.07f else 1.0f, label = "scale") val imageUrl = when (item.type) { - BaseItemKind.MOVIE -> item.movie?.heroImageUrl + BaseItemKind.MOVIE -> JellyfinImageHelper.finishImageUrl( + prefixImageUrl = item.movie?.imageUrlPrefix, + imageType = ImageType.PRIMARY + ) BaseItemKind.EPISODE -> item.episode?.heroImageUrl else -> null } diff --git a/app/src/main/java/hu/bbara/purefin/app/content/movie/MovieScreen.kt b/app/src/main/java/hu/bbara/purefin/app/content/movie/MovieScreen.kt index d25a1972..78858a49 100644 --- a/app/src/main/java/hu/bbara/purefin/app/content/movie/MovieScreen.kt +++ b/app/src/main/java/hu/bbara/purefin/app/content/movie/MovieScreen.kt @@ -35,12 +35,14 @@ import androidx.hilt.navigation.compose.hiltViewModel import hu.bbara.purefin.common.ui.MediaMetaChip import hu.bbara.purefin.common.ui.PurefinWaitingScreen import hu.bbara.purefin.common.ui.components.MediaHero +import hu.bbara.purefin.core.data.image.JellyfinImageHelper import hu.bbara.purefin.core.data.navigation.MovieDto import hu.bbara.purefin.core.model.CastMember import hu.bbara.purefin.core.model.Movie import hu.bbara.purefin.feature.download.DownloadState import hu.bbara.purefin.feature.shared.content.movie.MovieScreenViewModel import hu.bbara.purefin.ui.theme.AppTheme +import org.jellyfin.sdk.model.api.ImageType import java.util.UUID @Composable @@ -135,7 +137,7 @@ fun MediaHeroSection( .height(sectionHeight) ) { MediaHero( - imageUrl = movie.heroImageUrl, + imageUrl = JellyfinImageHelper.finishImageUrl(movie.imageUrlPrefix, ImageType.PRIMARY), backgroundColor = MaterialTheme.colorScheme.background, modifier = Modifier.fillMaxSize() ) @@ -209,7 +211,7 @@ private fun previewMovie(): Movie = runtime = "2h 44m", format = "Dolby Vision", synopsis = "A new blade runner uncovers a buried secret that forces him to trace the vanished footsteps of Rick Deckard.", - heroImageUrl = "https://images.unsplash.com/photo-1519608487953-e999c86e7455", + imageUrlPrefix = "https://images.unsplash.com/photo-1519608487953-e999c86e7455", audioTrack = "English 5.1", subtitles = "English CC", cast = listOf( diff --git a/app/src/main/java/hu/bbara/purefin/app/home/ui/HomeContent.kt b/app/src/main/java/hu/bbara/purefin/app/home/ui/HomeContent.kt index 4241fcac..ae4c4296 100644 --- a/app/src/main/java/hu/bbara/purefin/app/home/ui/HomeContent.kt +++ b/app/src/main/java/hu/bbara/purefin/app/home/ui/HomeContent.kt @@ -21,26 +21,19 @@ import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.runtime.snapshotFlow import androidx.compose.ui.Modifier -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import hu.bbara.purefin.app.home.ui.continuewatching.ContinueWatchingSection import hu.bbara.purefin.app.home.ui.featured.SuggestionsSection import hu.bbara.purefin.app.home.ui.library.LibraryPosterSection import hu.bbara.purefin.app.home.ui.nextup.NextUpSection import hu.bbara.purefin.app.home.ui.shared.HomeEmptyState -import hu.bbara.purefin.core.model.Episode -import hu.bbara.purefin.core.model.Movie -import hu.bbara.purefin.core.model.Series import hu.bbara.purefin.feature.shared.home.ContinueWatchingItem import hu.bbara.purefin.feature.shared.home.LibraryItem import hu.bbara.purefin.feature.shared.home.NextUpItem import hu.bbara.purefin.feature.shared.home.PosterItem import hu.bbara.purefin.feature.shared.home.SuggestedItem -import hu.bbara.purefin.ui.theme.AppTheme import org.jellyfin.sdk.model.UUID import org.jellyfin.sdk.model.api.BaseItemKind -import org.jellyfin.sdk.model.api.CollectionType -import java.util.UUID as JavaUuid @OptIn(ExperimentalMaterial3Api::class) @Composable @@ -169,266 +162,4 @@ fun HomeContent( } } } -} - -@Preview(name = "Home Full", showBackground = true, widthDp = 412, heightDp = 915) -@Composable -private fun HomeContentPreview() { - AppTheme(darkTheme = true) { - HomeContent( - libraries = homePreviewLibraries(), - libraryContent = homePreviewLibraryContent(), - suggestions = emptyList(), - continueWatching = homePreviewContinueWatching(), - nextUp = homePreviewNextUp(), - isRefreshing = false, - onRefresh = {}, - onMovieSelected = {}, - onSeriesSelected = {}, - onEpisodeSelected = { _, _, _ -> }, - onLibrarySelected = {}, - onBrowseLibrariesClick = {} - ) - } -} - -@Preview(name = "Home Libraries Only", showBackground = true, widthDp = 412, heightDp = 915) -@Composable -private fun HomeLibrariesOnlyPreview() { - AppTheme(darkTheme = true) { - HomeContent( - libraries = homePreviewLibraries(), - libraryContent = homePreviewLibraryContent(), - suggestions = emptyList(), - continueWatching = emptyList(), - nextUp = emptyList(), - isRefreshing = false, - onRefresh = {}, - onMovieSelected = {}, - onSeriesSelected = {}, - onEpisodeSelected = { _, _, _ -> }, - onLibrarySelected = {}, - onBrowseLibrariesClick = {} - ) - } -} - -@Preview(name = "Home Empty", showBackground = true, widthDp = 412, heightDp = 915) -@Composable -private fun HomeEmptyPreview() { - AppTheme(darkTheme = false) { - HomeContent( - libraries = emptyList(), - libraryContent = emptyMap(), - suggestions = emptyList(), - continueWatching = emptyList(), - nextUp = emptyList(), - isRefreshing = false, - onRefresh = {}, - onMovieSelected = {}, - onSeriesSelected = {}, - onEpisodeSelected = { _, _, _ -> }, - onLibrarySelected = {}, - onBrowseLibrariesClick = {} - ) - } -} - -internal fun homePreviewLibraries(): List { - return listOf( - LibraryItem( - id = JavaUuid.fromString("11111111-1111-1111-1111-111111111111"), - name = "Movies", - type = CollectionType.MOVIES, - posterUrl = "https://images.unsplash.com/photo-1517604931442-7e0c8ed2963c", - isEmpty = false - ), - LibraryItem( - id = JavaUuid.fromString("22222222-2222-2222-2222-222222222222"), - name = "Series", - type = CollectionType.TVSHOWS, - posterUrl = "https://images.unsplash.com/photo-1489599849927-2ee91cede3ba", - isEmpty = false - ) - ) -} - -internal fun homePreviewLibraryContent(): Map> { - val movie = homePreviewMovie( - id = "33333333-3333-3333-3333-333333333333", - title = "Blade Runner 2049", - year = "2017", - runtime = "2h 44m", - rating = "16+", - format = "Dolby Vision", - synopsis = "A young blade runner uncovers a buried secret that pulls him toward a vanished legend.", - heroImageUrl = "https://images.unsplash.com/photo-1519608487953-e999c86e7455", - progress = 42.0, - watched = false - ) - val secondMovie = homePreviewMovie( - id = "44444444-4444-4444-4444-444444444444", - title = "Arrival", - year = "2016", - runtime = "1h 56m", - rating = "12+", - format = "4K", - synopsis = "A linguist is recruited when mysterious spacecraft touch down around the world.", - heroImageUrl = "https://images.unsplash.com/photo-1500534314209-a25ddb2bd429", - progress = null, - watched = false - ) - val series = homePreviewSeries() - val episode = homePreviewEpisode( - id = "66666666-6666-6666-6666-666666666666", - title = "Signals", - index = 2, - releaseDate = "2025", - runtime = "48m", - rating = "16+", - progress = 18.0, - watched = false, - heroImageUrl = "https://images.unsplash.com/photo-1520034475321-cbe63696469a", - synopsis = "Anomalies around the station point to a cover-up." - ) - - return mapOf( - homePreviewLibraries()[0].id to listOf( - PosterItem(type = BaseItemKind.MOVIE, movie = movie), - PosterItem(type = BaseItemKind.MOVIE, movie = secondMovie) - ), - homePreviewLibraries()[1].id to listOf( - PosterItem(type = BaseItemKind.SERIES, series = series), - PosterItem(type = BaseItemKind.EPISODE, episode = episode) - ) - ) -} - -internal fun homePreviewContinueWatching(): List { - return listOf( - ContinueWatchingItem( - type = BaseItemKind.MOVIE, - movie = homePreviewMovie( - id = "77777777-7777-7777-7777-777777777777", - title = "Dune: Part Two", - year = "2024", - runtime = "2h 46m", - rating = "13+", - format = "IMAX", - synopsis = "Paul Atreides unites with the Fremen while seeking justice and revenge.", - heroImageUrl = "https://images.unsplash.com/photo-1446776811953-b23d57bd21aa", - progress = 58.0, - watched = false - ) - ), - ContinueWatchingItem( - type = BaseItemKind.EPISODE, - episode = homePreviewEpisode( - id = "88888888-8888-8888-8888-888888888888", - title = "A Fresh Start", - index = 1, - releaseDate = "2025", - runtime = "51m", - rating = "16+", - progress = 23.0, - watched = false, - heroImageUrl = "https://images.unsplash.com/photo-1497032205916-ac775f0649ae", - synopsis = "A fractured crew tries to reassemble after a year apart." - ) - ) - ) -} - -internal fun homePreviewNextUp(): List { - return listOf( - NextUpItem( - episode = homePreviewEpisode( - id = "99999999-9999-9999-9999-999999999999", - title = "Return Window", - index = 3, - releaseDate = "2025", - runtime = "54m", - rating = "16+", - progress = null, - watched = false, - heroImageUrl = "https://images.unsplash.com/photo-1500530855697-b586d89ba3ee", - synopsis = "A high-risk jump changes the rules of the mission." - ) - ) - ) -} - -internal fun homePreviewMovie( - id: String, - title: String, - year: String, - runtime: String, - rating: String, - format: String, - synopsis: String, - heroImageUrl: String, - progress: Double?, - watched: Boolean -): Movie { - return Movie( - id = JavaUuid.fromString(id), - libraryId = JavaUuid.fromString("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"), - title = title, - progress = progress, - watched = watched, - year = year, - rating = rating, - runtime = runtime, - format = format, - synopsis = synopsis, - heroImageUrl = heroImageUrl, - audioTrack = "English 5.1", - subtitles = "English CC", - cast = emptyList() - ) -} - -internal fun homePreviewSeries(): Series { - return Series( - id = JavaUuid.fromString("bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"), - libraryId = JavaUuid.fromString("cccccccc-cccc-cccc-cccc-cccccccccccc"), - name = "Orbital", - synopsis = "A reluctant crew returns to a damaged station as political pressure mounts on Earth.", - year = "2025", - heroImageUrl = "https://images.unsplash.com/photo-1520034475321-cbe63696469a", - unwatchedEpisodeCount = 4, - seasonCount = 2, - seasons = emptyList(), - cast = emptyList() - ) -} - -internal fun homePreviewEpisode( - id: String, - title: String, - index: Int, - releaseDate: String, - runtime: String, - rating: String, - progress: Double?, - watched: Boolean, - heroImageUrl: String, - synopsis: String -): Episode { - return Episode( - id = JavaUuid.fromString(id), - seriesId = JavaUuid.fromString("dddddddd-dddd-dddd-dddd-dddddddddddd"), - seasonId = JavaUuid.fromString("eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee"), - index = index, - title = title, - synopsis = synopsis, - releaseDate = releaseDate, - rating = rating, - runtime = runtime, - progress = progress, - watched = watched, - format = "4K", - heroImageUrl = heroImageUrl, - cast = emptyList() - ) -} +} \ No newline at end of file diff --git a/app/src/main/java/hu/bbara/purefin/app/home/ui/continuewatching/ContinueWatchingCard.kt b/app/src/main/java/hu/bbara/purefin/app/home/ui/continuewatching/ContinueWatchingCard.kt index d693f0f0..f17e819d 100644 --- a/app/src/main/java/hu/bbara/purefin/app/home/ui/continuewatching/ContinueWatchingCard.kt +++ b/app/src/main/java/hu/bbara/purefin/app/home/ui/continuewatching/ContinueWatchingCard.kt @@ -25,9 +25,11 @@ import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import hu.bbara.purefin.common.ui.components.MediaProgressBar import hu.bbara.purefin.common.ui.components.PurefinAsyncImage +import hu.bbara.purefin.core.data.image.JellyfinImageHelper import hu.bbara.purefin.feature.shared.home.ContinueWatchingItem import org.jellyfin.sdk.model.UUID import org.jellyfin.sdk.model.api.BaseItemKind +import org.jellyfin.sdk.model.api.ImageType @Composable internal fun ContinueWatchingCard( @@ -51,7 +53,10 @@ internal fun ContinueWatchingCard( else -> "" } val imageUrl = when (item.type) { - BaseItemKind.MOVIE -> item.movie?.heroImageUrl + BaseItemKind.MOVIE -> JellyfinImageHelper.finishImageUrl( + prefixImageUrl = item.movie?.imageUrlPrefix, + imageType = ImageType.PRIMARY + ) BaseItemKind.EPISODE -> item.episode?.heroImageUrl else -> null } diff --git a/core/data/src/main/java/hu/bbara/purefin/core/data/InMemoryAppContentRepository.kt b/core/data/src/main/java/hu/bbara/purefin/core/data/InMemoryAppContentRepository.kt index d4df8798..d2c6db11 100644 --- a/core/data/src/main/java/hu/bbara/purefin/core/data/InMemoryAppContentRepository.kt +++ b/core/data/src/main/java/hu/bbara/purefin/core/data/InMemoryAppContentRepository.kt @@ -433,10 +433,9 @@ class InMemoryAppContentRepository @Inject constructor( runtime = formatRuntime(this.runTimeTicks), synopsis = this.overview ?: "No synopsis available", format = container?.uppercase() ?: "VIDEO", - heroImageUrl = JellyfinImageHelper.toImageUrl( + imageUrlPrefix = JellyfinImageHelper.toPrefixImageUrl( url = serverUrl, itemId = this.id, - type = ImageType.PRIMARY ), subtitles = "ENG", audioTrack = "ENG", diff --git a/core/data/src/main/java/hu/bbara/purefin/core/data/image/JellyfinImageHelper.kt b/core/data/src/main/java/hu/bbara/purefin/core/data/image/JellyfinImageHelper.kt index 47aaced5..bd135b39 100644 --- a/core/data/src/main/java/hu/bbara/purefin/core/data/image/JellyfinImageHelper.kt +++ b/core/data/src/main/java/hu/bbara/purefin/core/data/image/JellyfinImageHelper.kt @@ -31,7 +31,10 @@ class JellyfinImageHelper { .toString() } - fun finishImageUrl(prefixImageUrl: String, imageType: ImageType): String { + fun finishImageUrl(prefixImageUrl: String?, imageType: ImageType): String { + if (prefixImageUrl.isNullOrEmpty()) { + return "" + } return StringBuilder() .append(prefixImageUrl) .append(imageType.serialName) diff --git a/core/data/src/main/java/hu/bbara/purefin/core/data/room/entity/MovieEntity.kt b/core/data/src/main/java/hu/bbara/purefin/core/data/room/entity/MovieEntity.kt index cf72c6b5..f952baf8 100644 --- a/core/data/src/main/java/hu/bbara/purefin/core/data/room/entity/MovieEntity.kt +++ b/core/data/src/main/java/hu/bbara/purefin/core/data/room/entity/MovieEntity.kt @@ -1,7 +1,6 @@ package hu.bbara.purefin.core.data.room.entity import androidx.room.Entity -import androidx.room.ForeignKey import androidx.room.Index import androidx.room.PrimaryKey import java.util.UUID @@ -21,7 +20,7 @@ data class MovieEntity( val runtime: String, val format: String, val synopsis: String, - val heroImageUrl: String, + val imageUrlPrefix: String, val audioTrack: String, val subtitles: String ) diff --git a/core/data/src/main/java/hu/bbara/purefin/core/data/room/offline/OfflineMediaDatabase.kt b/core/data/src/main/java/hu/bbara/purefin/core/data/room/offline/OfflineMediaDatabase.kt index dff7c5f1..b2baa974 100644 --- a/core/data/src/main/java/hu/bbara/purefin/core/data/room/offline/OfflineMediaDatabase.kt +++ b/core/data/src/main/java/hu/bbara/purefin/core/data/room/offline/OfflineMediaDatabase.kt @@ -23,7 +23,7 @@ import hu.bbara.purefin.core.data.room.entity.SmartDownloadEntity EpisodeEntity::class, SmartDownloadEntity::class, ], - version = 6, + version = 7, exportSchema = false ) @TypeConverters(UuidConverters::class) diff --git a/core/data/src/main/java/hu/bbara/purefin/core/data/room/offline/OfflineRoomMediaLocalDataSource.kt b/core/data/src/main/java/hu/bbara/purefin/core/data/room/offline/OfflineRoomMediaLocalDataSource.kt index 81ce808c..91355ec1 100644 --- a/core/data/src/main/java/hu/bbara/purefin/core/data/room/offline/OfflineRoomMediaLocalDataSource.kt +++ b/core/data/src/main/java/hu/bbara/purefin/core/data/room/offline/OfflineRoomMediaLocalDataSource.kt @@ -208,7 +208,7 @@ class OfflineRoomMediaLocalDataSource( runtime = runtime, format = format, synopsis = synopsis, - heroImageUrl = heroImageUrl, + imageUrlPrefix = imageUrlPrefix, audioTrack = audioTrack, subtitles = subtitles ) @@ -260,7 +260,7 @@ class OfflineRoomMediaLocalDataSource( runtime = runtime, format = format, synopsis = synopsis, - heroImageUrl = heroImageUrl, + imageUrlPrefix = imageUrlPrefix, audioTrack = audioTrack, subtitles = subtitles, cast = emptyList() diff --git a/core/model/src/main/java/hu/bbara/purefin/core/model/Movie.kt b/core/model/src/main/java/hu/bbara/purefin/core/model/Movie.kt index 74eb21ac..5f185b88 100644 --- a/core/model/src/main/java/hu/bbara/purefin/core/model/Movie.kt +++ b/core/model/src/main/java/hu/bbara/purefin/core/model/Movie.kt @@ -13,7 +13,7 @@ data class Movie( val runtime: String, val format: String, val synopsis: String, - val heroImageUrl: String, + val imageUrlPrefix: String, val audioTrack: String, val subtitles: String, val cast: List diff --git a/core/player/src/main/java/hu/bbara/purefin/core/player/data/PlayerMediaRepository.kt b/core/player/src/main/java/hu/bbara/purefin/core/player/data/PlayerMediaRepository.kt index 184488a3..b86f08d4 100644 --- a/core/player/src/main/java/hu/bbara/purefin/core/player/data/PlayerMediaRepository.kt +++ b/core/player/src/main/java/hu/bbara/purefin/core/player/data/PlayerMediaRepository.kt @@ -124,6 +124,7 @@ class PlayerMediaRepository @Inject constructor( } } + @OptIn(UnstableApi::class) private suspend fun buildOfflineMediaItem(mediaId: UUID): Pair? { val download = downloadManager.downloadIndex.getDownload(mediaId.toString()) ?.takeIf { it.state == Download.STATE_COMPLETED } @@ -138,7 +139,7 @@ class PlayerMediaRepository @Inject constructor( } val subtitle = episode?.let { episodeSubtitle(null, it.index) } val artworkUrl = when { - movie != null -> movie.heroImageUrl + movie != null -> JellyfinImageHelper.finishImageUrl(movie.imageUrlPrefix, ImageType.PRIMARY) episode != null -> episode.heroImageUrl else -> JellyfinImageHelper.toImageUrl(serverUrl, mediaId, ImageType.PRIMARY) } diff --git a/feature/download/src/main/java/hu/bbara/purefin/feature/download/MediaDownloadManager.kt b/feature/download/src/main/java/hu/bbara/purefin/feature/download/MediaDownloadManager.kt index f73ba5c8..cf967975 100644 --- a/feature/download/src/main/java/hu/bbara/purefin/feature/download/MediaDownloadManager.kt +++ b/feature/download/src/main/java/hu/bbara/purefin/feature/download/MediaDownloadManager.kt @@ -23,7 +23,6 @@ import hu.bbara.purefin.core.model.Season import hu.bbara.purefin.core.model.Series import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.coroutineScope -import kotlinx.coroutines.launch import kotlinx.coroutines.delay import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow @@ -32,6 +31,7 @@ import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import org.jellyfin.sdk.model.api.BaseItemDto import org.jellyfin.sdk.model.api.ImageType @@ -156,10 +156,9 @@ class MediaDownloadManager @Inject constructor( runtime = formatRuntime(itemInfo.runTimeTicks), synopsis = itemInfo.overview ?: "No synopsis available", format = itemInfo.container?.uppercase() ?: "VIDEO", - heroImageUrl = JellyfinImageHelper.toImageUrl( + imageUrlPrefix = JellyfinImageHelper.toPrefixImageUrl( url = serverUrl, - itemId = itemInfo.id, - type = ImageType.PRIMARY + itemId = itemInfo.id ), subtitles = "ENG", audioTrack = "ENG", diff --git a/feature/shared/src/main/java/hu/bbara/purefin/feature/shared/download/DownloadsViewModel.kt b/feature/shared/src/main/java/hu/bbara/purefin/feature/shared/download/DownloadsViewModel.kt index f09375ea..cd97a83c 100644 --- a/feature/shared/src/main/java/hu/bbara/purefin/feature/shared/download/DownloadsViewModel.kt +++ b/feature/shared/src/main/java/hu/bbara/purefin/feature/shared/download/DownloadsViewModel.kt @@ -4,6 +4,7 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel import hu.bbara.purefin.core.data.OfflineMediaRepository +import hu.bbara.purefin.core.data.image.JellyfinImageHelper import hu.bbara.purefin.core.data.navigation.MovieDto import hu.bbara.purefin.core.data.navigation.NavigationManager import hu.bbara.purefin.core.data.navigation.Route @@ -16,6 +17,7 @@ import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch import org.jellyfin.sdk.model.UUID import org.jellyfin.sdk.model.api.BaseItemKind +import org.jellyfin.sdk.model.api.ImageType import javax.inject.Inject @HiltViewModel @@ -70,7 +72,7 @@ class DownloadsViewModel @Inject constructor( contentId = contentId, title = movie.title, subtitle = "", - imageUrl = movie.heroImageUrl, + imageUrl = JellyfinImageHelper.finishImageUrl(movie.imageUrlPrefix, ImageType.PRIMARY), progress = progress ) } else { diff --git a/feature/shared/src/main/java/hu/bbara/purefin/feature/shared/home/HomeModels.kt b/feature/shared/src/main/java/hu/bbara/purefin/feature/shared/home/HomeModels.kt index 947c34b7..785a61ac 100644 --- a/feature/shared/src/main/java/hu/bbara/purefin/feature/shared/home/HomeModels.kt +++ b/feature/shared/src/main/java/hu/bbara/purefin/feature/shared/home/HomeModels.kt @@ -1,11 +1,13 @@ package hu.bbara.purefin.feature.shared.home +import hu.bbara.purefin.core.data.image.JellyfinImageHelper import hu.bbara.purefin.core.model.Episode import hu.bbara.purefin.core.model.Movie import hu.bbara.purefin.core.model.Series import org.jellyfin.sdk.model.UUID import org.jellyfin.sdk.model.api.BaseItemKind import org.jellyfin.sdk.model.api.CollectionType +import org.jellyfin.sdk.model.api.ImageType sealed interface SuggestedItem { @@ -74,7 +76,10 @@ data class SuggestedMovie ( override val id: UUID = movie.id, override val title: String = movie.title, override val description: String = movie.synopsis, - override val imageUrl: String = movie.heroImageUrl + override val imageUrl: String = JellyfinImageHelper.finishImageUrl( + prefixImageUrl = movie.imageUrlPrefix, + imageType = ImageType.PRIMARY + ) ) : SuggestedItem data class ContinueWatchingItem( @@ -139,7 +144,7 @@ data class PosterItem( else -> throw IllegalArgumentException("Invalid type: $type") } val imageUrl: String = when (type) { - BaseItemKind.MOVIE -> movie!!.heroImageUrl + BaseItemKind.MOVIE -> movie!!.imageUrlPrefix BaseItemKind.EPISODE -> episode!!.heroImageUrl BaseItemKind.SERIES -> series!!.heroImageUrl else -> throw IllegalArgumentException("Invalid type: $type")