Add overview dialog

This commit is contained in:
Damontecres 2025-09-30 12:21:24 -04:00
parent f96ed850b7
commit 911bef1200
No known key found for this signature in database
5 changed files with 112 additions and 10 deletions

View file

@ -11,6 +11,7 @@ import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
@ -241,10 +242,10 @@ fun ScrollableDialog(
modifier =
modifier
.width(600.dp)
.height(380.dp)
.heightIn(max = 380.dp)
.focusable()
.background(
MaterialTheme.colorScheme.surface,
MaterialTheme.colorScheme.surfaceColorAtElevation(3.dp),
shape = RoundedCornerShape(8.dp),
).onKeyEvent {
if (it.type == KeyEventType.KeyUp) {

View file

@ -0,0 +1,56 @@
package com.github.damontecres.dolphin.ui.data
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.lazy.items
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.tv.material3.MaterialTheme
import androidx.tv.material3.Text
import com.github.damontecres.dolphin.ui.components.ScrollableDialog
import com.github.damontecres.dolphin.ui.isNotNullOrBlank
data class ItemDetailsDialogInfo(
val title: String,
val overview: String?,
val files: List<String>,
)
@Composable
fun ItemDetailsDialog(
info: ItemDetailsDialogInfo,
onDismissRequest: () -> Unit,
modifier: Modifier = Modifier,
) {
ScrollableDialog(
onDismissRequest = onDismissRequest,
modifier = modifier,
) {
item {
Text(
text = info.title,
style = MaterialTheme.typography.titleMedium,
)
}
if (info.overview.isNotNullOrBlank()) {
item {
Text(
text = info.overview,
style = MaterialTheme.typography.bodyMedium,
)
}
}
if (info.files.isNotEmpty()) {
item {
Spacer(Modifier.height(8.dp))
}
}
items(info.files) { file ->
Text(
text = "- $file",
style = MaterialTheme.typography.bodyMedium,
)
}
}
}

View file

@ -100,8 +100,7 @@ class SeriesViewModel
sortOrder = listOf(SortOrder.ASCENDING),
fields =
listOf(
ItemFields.PRIMARY_IMAGE_ASPECT_RATIO,
ItemFields.CHILD_COUNT,
ItemFields.MEDIA_SOURCES,
ItemFields.MEDIA_STREAMS,
ItemFields.OVERVIEW,
),

View file

@ -15,6 +15,8 @@ import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.tv.material3.Text
import com.github.damontecres.dolphin.preferences.UserPreferences
import com.github.damontecres.dolphin.ui.OneTimeLaunchedEffect
import com.github.damontecres.dolphin.ui.data.ItemDetailsDialog
import com.github.damontecres.dolphin.ui.data.ItemDetailsDialogInfo
import com.github.damontecres.dolphin.ui.detail.SeriesViewModel
import com.github.damontecres.dolphin.ui.nav.Destination
import com.github.damontecres.dolphin.ui.nav.NavigationManager
@ -57,6 +59,8 @@ fun SeriesOverview(
),
) { mutableStateOf(initialSeasonEpisode) }
var overviewDialog by remember { mutableStateOf<ItemDetailsDialogInfo?>(null) }
LaunchedEffect(episodes) {
if (episodes.isNotEmpty()) {
// TODO focus on first episode when changing seasons
@ -90,9 +94,48 @@ fun SeriesOverview(
navigationManager.navigateTo(Destination.Playback(it.id, resumePosition.inWholeMilliseconds, it))
},
onLongClick = {
// TODO
},
playOnClick = { resume ->
episodes.getOrNull(seasonEpisode.episode)?.let {
navigationManager.navigateTo(
Destination.Playback(
it.id,
resume.inWholeMilliseconds,
it,
),
)
}
},
watchOnClick = {
// TODO toggle watched state
},
moreOnClick = {
// TODO show more actions
},
overviewOnClick = {
episodes.getOrNull(seasonEpisode.episode)?.let {
overviewDialog =
ItemDetailsDialogInfo(
title = it.name ?: "Unknown",
overview = it.data.overview,
files =
it.data.mediaSources
?.mapNotNull { it.path }
.orEmpty(),
)
}
},
modifier = modifier,
)
}
}
overviewDialog?.let { info ->
ItemDetailsDialog(
info = info,
onDismissRequest = { overviewDialog = null },
modifier = Modifier,
)
}
}

View file

@ -42,6 +42,7 @@ import com.github.damontecres.dolphin.data.model.BaseItem
import com.github.damontecres.dolphin.ui.cards.BannerCard
import com.github.damontecres.dolphin.ui.ifElse
import com.github.damontecres.dolphin.ui.isNotNullOrBlank
import kotlin.time.Duration
@Composable
fun SeriesOverviewContent(
@ -54,6 +55,10 @@ fun SeriesOverviewContent(
onFocus: (SeasonEpisode) -> Unit,
onClick: (BaseItem) -> Unit,
onLongClick: (BaseItem) -> Unit,
playOnClick: (Duration) -> Unit,
watchOnClick: () -> Unit,
moreOnClick: () -> Unit,
overviewOnClick: () -> Unit,
modifier: Modifier = Modifier,
) {
val bringIntoViewRequester = remember { BringIntoViewRequester() }
@ -156,9 +161,7 @@ fun SeriesOverviewContent(
focusedEpisode?.let { ep ->
FocusedEpisodeHeader(
ep = ep,
overviewOnClick = {
// TODO show full overview dialog
},
overviewOnClick = overviewOnClick,
modifier = Modifier.fillMaxWidth(.66f),
)
}
@ -199,9 +202,9 @@ fun SeriesOverviewContent(
focusedEpisode?.let { ep ->
FocusedEpisodeFooter(
ep = ep,
playOnClick = {},
moreOnClick = {},
watchOnClick = {},
playOnClick = playOnClick,
moreOnClick = moreOnClick,
watchOnClick = watchOnClick,
modifier =
Modifier
.fillMaxWidth()