mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-07-08 23:51:21 +02:00
Add overview dialog
This commit is contained in:
parent
f96ed850b7
commit
911bef1200
5 changed files with 112 additions and 10 deletions
|
|
@ -11,6 +11,7 @@ import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.BoxScope
|
import androidx.compose.foundation.layout.BoxScope
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.heightIn
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
|
|
@ -241,10 +242,10 @@ fun ScrollableDialog(
|
||||||
modifier =
|
modifier =
|
||||||
modifier
|
modifier
|
||||||
.width(600.dp)
|
.width(600.dp)
|
||||||
.height(380.dp)
|
.heightIn(max = 380.dp)
|
||||||
.focusable()
|
.focusable()
|
||||||
.background(
|
.background(
|
||||||
MaterialTheme.colorScheme.surface,
|
MaterialTheme.colorScheme.surfaceColorAtElevation(3.dp),
|
||||||
shape = RoundedCornerShape(8.dp),
|
shape = RoundedCornerShape(8.dp),
|
||||||
).onKeyEvent {
|
).onKeyEvent {
|
||||||
if (it.type == KeyEventType.KeyUp) {
|
if (it.type == KeyEventType.KeyUp) {
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -100,8 +100,7 @@ class SeriesViewModel
|
||||||
sortOrder = listOf(SortOrder.ASCENDING),
|
sortOrder = listOf(SortOrder.ASCENDING),
|
||||||
fields =
|
fields =
|
||||||
listOf(
|
listOf(
|
||||||
ItemFields.PRIMARY_IMAGE_ASPECT_RATIO,
|
ItemFields.MEDIA_SOURCES,
|
||||||
ItemFields.CHILD_COUNT,
|
|
||||||
ItemFields.MEDIA_STREAMS,
|
ItemFields.MEDIA_STREAMS,
|
||||||
ItemFields.OVERVIEW,
|
ItemFields.OVERVIEW,
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,8 @@ import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
||||||
import androidx.tv.material3.Text
|
import androidx.tv.material3.Text
|
||||||
import com.github.damontecres.dolphin.preferences.UserPreferences
|
import com.github.damontecres.dolphin.preferences.UserPreferences
|
||||||
import com.github.damontecres.dolphin.ui.OneTimeLaunchedEffect
|
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.detail.SeriesViewModel
|
||||||
import com.github.damontecres.dolphin.ui.nav.Destination
|
import com.github.damontecres.dolphin.ui.nav.Destination
|
||||||
import com.github.damontecres.dolphin.ui.nav.NavigationManager
|
import com.github.damontecres.dolphin.ui.nav.NavigationManager
|
||||||
|
|
@ -57,6 +59,8 @@ fun SeriesOverview(
|
||||||
),
|
),
|
||||||
) { mutableStateOf(initialSeasonEpisode) }
|
) { mutableStateOf(initialSeasonEpisode) }
|
||||||
|
|
||||||
|
var overviewDialog by remember { mutableStateOf<ItemDetailsDialogInfo?>(null) }
|
||||||
|
|
||||||
LaunchedEffect(episodes) {
|
LaunchedEffect(episodes) {
|
||||||
if (episodes.isNotEmpty()) {
|
if (episodes.isNotEmpty()) {
|
||||||
// TODO focus on first episode when changing seasons
|
// TODO focus on first episode when changing seasons
|
||||||
|
|
@ -90,9 +94,48 @@ fun SeriesOverview(
|
||||||
navigationManager.navigateTo(Destination.Playback(it.id, resumePosition.inWholeMilliseconds, it))
|
navigationManager.navigateTo(Destination.Playback(it.id, resumePosition.inWholeMilliseconds, it))
|
||||||
},
|
},
|
||||||
onLongClick = {
|
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,
|
modifier = modifier,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
overviewDialog?.let { info ->
|
||||||
|
ItemDetailsDialog(
|
||||||
|
info = info,
|
||||||
|
onDismissRequest = { overviewDialog = null },
|
||||||
|
modifier = Modifier,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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.cards.BannerCard
|
||||||
import com.github.damontecres.dolphin.ui.ifElse
|
import com.github.damontecres.dolphin.ui.ifElse
|
||||||
import com.github.damontecres.dolphin.ui.isNotNullOrBlank
|
import com.github.damontecres.dolphin.ui.isNotNullOrBlank
|
||||||
|
import kotlin.time.Duration
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun SeriesOverviewContent(
|
fun SeriesOverviewContent(
|
||||||
|
|
@ -54,6 +55,10 @@ fun SeriesOverviewContent(
|
||||||
onFocus: (SeasonEpisode) -> Unit,
|
onFocus: (SeasonEpisode) -> Unit,
|
||||||
onClick: (BaseItem) -> Unit,
|
onClick: (BaseItem) -> Unit,
|
||||||
onLongClick: (BaseItem) -> Unit,
|
onLongClick: (BaseItem) -> Unit,
|
||||||
|
playOnClick: (Duration) -> Unit,
|
||||||
|
watchOnClick: () -> Unit,
|
||||||
|
moreOnClick: () -> Unit,
|
||||||
|
overviewOnClick: () -> Unit,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
val bringIntoViewRequester = remember { BringIntoViewRequester() }
|
val bringIntoViewRequester = remember { BringIntoViewRequester() }
|
||||||
|
|
@ -156,9 +161,7 @@ fun SeriesOverviewContent(
|
||||||
focusedEpisode?.let { ep ->
|
focusedEpisode?.let { ep ->
|
||||||
FocusedEpisodeHeader(
|
FocusedEpisodeHeader(
|
||||||
ep = ep,
|
ep = ep,
|
||||||
overviewOnClick = {
|
overviewOnClick = overviewOnClick,
|
||||||
// TODO show full overview dialog
|
|
||||||
},
|
|
||||||
modifier = Modifier.fillMaxWidth(.66f),
|
modifier = Modifier.fillMaxWidth(.66f),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -199,9 +202,9 @@ fun SeriesOverviewContent(
|
||||||
focusedEpisode?.let { ep ->
|
focusedEpisode?.let { ep ->
|
||||||
FocusedEpisodeFooter(
|
FocusedEpisodeFooter(
|
||||||
ep = ep,
|
ep = ep,
|
||||||
playOnClick = {},
|
playOnClick = playOnClick,
|
||||||
moreOnClick = {},
|
moreOnClick = moreOnClick,
|
||||||
watchOnClick = {},
|
watchOnClick = watchOnClick,
|
||||||
modifier =
|
modifier =
|
||||||
Modifier
|
Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue