Header for discover page

This commit is contained in:
Damontecres 2025-12-23 18:29:22 -05:00
parent 22348a5adc
commit d814d533ab
No known key found for this signature in database
3 changed files with 174 additions and 118 deletions

View file

@ -62,6 +62,8 @@ data class DiscoverItem(
val id: Int,
val type: SeerrItemType,
val title: String?,
val subtitle: String?,
val overview: String?,
val availability: SeerrAvailability,
val releaseDate: String?,
val posterPath: String?,
@ -75,6 +77,8 @@ data class DiscoverItem(
id = movie.id,
type = SeerrItemType.MOVIE,
title = movie.title,
subtitle = null,
overview = movie.overview,
availability = SeerrAvailability.from(movie.mediaInfo?.status) ?: SeerrAvailability.UNKNOWN,
releaseDate = movie.releaseDate,
posterPath = movie.posterPath,
@ -86,6 +90,8 @@ data class DiscoverItem(
id = movie.id ?: -1,
type = SeerrItemType.MOVIE,
title = movie.title,
subtitle = null,
overview = movie.overview,
availability = SeerrAvailability.from(movie.mediaInfo?.status) ?: SeerrAvailability.UNKNOWN,
releaseDate = movie.releaseDate,
posterPath = movie.posterPath,
@ -97,6 +103,8 @@ data class DiscoverItem(
id = tv.id!!,
type = SeerrItemType.MOVIE,
title = tv.name,
subtitle = null,
overview = tv.overview,
availability = SeerrAvailability.from(tv.mediaInfo?.status) ?: SeerrAvailability.UNKNOWN,
releaseDate = tv.firstAirDate,
posterPath = tv.posterPath,
@ -108,6 +116,8 @@ data class DiscoverItem(
id = search.id,
type = SeerrItemType.fromString(search.mediaType),
title = search.title ?: search.name,
subtitle = null,
overview = search.overview,
availability =
SeerrAvailability.from(search.mediaInfo?.status)
?: SeerrAvailability.UNKNOWN,

View file

@ -437,12 +437,40 @@ fun HomePageHeader(
modifier: Modifier = Modifier,
) {
item?.let {
val isEpisode = item.type == BaseItemKind.EPISODE
val dto = item.data
HomePageHeader(
title = item.title,
subtitle = if (isEpisode) dto.name else null,
overview = dto.overview,
overviewTwoLines = isEpisode,
quickDetails = {
when (item.type) {
BaseItemKind.EPISODE -> EpisodeQuickDetails(dto, Modifier)
BaseItemKind.SERIES -> SeriesQuickDetails(dto, Modifier)
else -> MovieQuickDetails(dto, Modifier)
}
},
modifier = modifier,
)
}
}
@Composable
fun HomePageHeader(
title: String?,
subtitle: String?,
overview: String?,
overviewTwoLines: Boolean,
quickDetails: (@Composable () -> Unit)?,
modifier: Modifier = Modifier,
) {
Column(
verticalArrangement = Arrangement.spacedBy(4.dp),
modifier = modifier,
) {
item.title?.let {
title?.let {
Text(
text = it,
style = MaterialTheme.typography.headlineMedium.copy(fontWeight = FontWeight.SemiBold),
@ -459,9 +487,9 @@ fun HomePageHeader(
.fillMaxWidth(.6f)
.fillMaxHeight(),
) {
val isEpisode = item.type == BaseItemKind.EPISODE
val subtitle = if (isEpisode) dto.name else null
val overview = dto.overview
// val isEpisode = item.type == BaseItemKind.EPISODE
// val subtitle = if (isEpisode) dto.name else null
// val overview = dto.overview
subtitle?.let {
Text(
text = subtitle,
@ -471,22 +499,18 @@ fun HomePageHeader(
overflow = TextOverflow.Ellipsis,
)
}
when (item.type) {
BaseItemKind.EPISODE -> EpisodeQuickDetails(dto, Modifier)
BaseItemKind.SERIES -> SeriesQuickDetails(dto, Modifier)
else -> MovieQuickDetails(dto, Modifier)
}
quickDetails?.invoke()
val overviewModifier =
Modifier
.padding(0.dp)
.height(48.dp + if (!isEpisode) 12.dp else 0.dp)
.height(48.dp + if (!overviewTwoLines) 12.dp else 0.dp)
.width(400.dp)
if (overview.isNotNullOrBlank()) {
Text(
text = overview,
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurface,
maxLines = if (isEpisode) 2 else 3,
maxLines = if (overviewTwoLines) 2 else 3,
overflow = TextOverflow.Ellipsis,
modifier = overviewModifier,
)
@ -495,5 +519,4 @@ fun HomePageHeader(
}
}
}
}
}

View file

@ -2,6 +2,7 @@ package com.github.damontecres.wholphin.ui.seerr
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
@ -31,6 +32,7 @@ import com.github.damontecres.wholphin.ui.cards.DiscoverItemCard
import com.github.damontecres.wholphin.ui.cards.ItemRow
import com.github.damontecres.wholphin.ui.data.RowColumn
import com.github.damontecres.wholphin.ui.launchIO
import com.github.damontecres.wholphin.ui.main.HomePageHeader
import com.github.damontecres.wholphin.ui.nav.Destination
import com.github.damontecres.wholphin.ui.rememberPosition
import com.github.damontecres.wholphin.ui.setValueOnMain
@ -38,7 +40,6 @@ import com.github.damontecres.wholphin.ui.tryRequestFocus
import dagger.hilt.android.lifecycle.HiltViewModel
import org.jellyfin.sdk.api.client.ApiClient
import org.jellyfin.sdk.model.api.BaseItemKind
import timber.log.Timber
import javax.inject.Inject
@HiltViewModel
@ -99,21 +100,42 @@ fun SeerrDiscoverPage(
LaunchedEffect(movies) { if (movies.isNotEmpty()) focusRequester.tryRequestFocus() }
val scrollState = rememberScrollState()
var position by rememberPosition(0, 0)
var position by rememberPosition()
LaunchedEffect(position) {
position.let {
val item = if (it.row == 0) movies.getOrNull(it.column) else tv.getOrNull(it.column)
Timber.v("Backdrop for $item")
viewModel.updateBackdrop(item)
}
}
val focusedItem =
remember(position) {
position.let {
if (it.row == 0) movies.getOrNull(it.column) else tv.getOrNull(it.column)
}
}
Column(
verticalArrangement = Arrangement.spacedBy(16.dp),
modifier = modifier,
) {
HomePageHeader(
title = focusedItem?.title,
subtitle = focusedItem?.subtitle,
overview = focusedItem?.overview,
overviewTwoLines = true,
quickDetails = {
// TODO
},
modifier =
modifier
Modifier
.padding(top = 48.dp, bottom = 32.dp, start = 32.dp)
.fillMaxHeight(.33f),
)
Column(
verticalArrangement = Arrangement.spacedBy(8.dp),
modifier =
Modifier
.verticalScroll(scrollState)
.padding(16.dp),
.padding(horizontal = 16.dp),
) {
ItemRow(
title = stringResource(R.string.movies),
@ -179,4 +201,5 @@ fun SeerrDiscoverPage(
},
)
}
}
}