mirror of
https://github.com/bbara04/Purefin.git
synced 2026-07-23 19:26:50 +00:00
refactor: update image handling in Movie dto to use imageUrlPrefix and JellyfinImageHelper
This commit is contained in:
@@ -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(
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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
|
||||
@@ -170,265 +163,3 @@ 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<LibraryItem> {
|
||||
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<UUID, List<PosterItem>> {
|
||||
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<ContinueWatchingItem> {
|
||||
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<NextUpItem> {
|
||||
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()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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<CastMember>
|
||||
|
||||
@@ -124,6 +124,7 @@ class PlayerMediaRepository @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(UnstableApi::class)
|
||||
private suspend fun buildOfflineMediaItem(mediaId: UUID): Pair<MediaItem, Long?>? {
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user