mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-07-08 15:50:16 +02:00
Move stream labels to top of description (#323)
Follow up to #279 Closes #162 Move the stream labels to the top under the dot-separated details. Also move the rating up to the dot-separated details line and add it to home page.
This commit is contained in:
parent
5b96be6662
commit
0bfe3d2653
10 changed files with 114 additions and 112 deletions
|
|
@ -1,5 +1,6 @@
|
||||||
package com.github.damontecres.wholphin.ui.components
|
package com.github.damontecres.wholphin.ui.components
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.BoxScope
|
||||||
import androidx.compose.foundation.layout.fillMaxHeight
|
import androidx.compose.foundation.layout.fillMaxHeight
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
|
|
@ -14,7 +15,7 @@ import coil3.compose.AsyncImage
|
||||||
import com.github.damontecres.wholphin.ui.isNotNullOrBlank
|
import com.github.damontecres.wholphin.ui.isNotNullOrBlank
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun DetailsBackdropImage(
|
fun BoxScope.DetailsBackdropImage(
|
||||||
backdropImageUrl: String?,
|
backdropImageUrl: String?,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
|
|
@ -23,10 +24,11 @@ fun DetailsBackdropImage(
|
||||||
AsyncImage(
|
AsyncImage(
|
||||||
model = backdropImageUrl,
|
model = backdropImageUrl,
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
contentScale = ContentScale.Crop,
|
contentScale = ContentScale.Fit,
|
||||||
alignment = Alignment.TopEnd,
|
alignment = Alignment.TopEnd,
|
||||||
modifier =
|
modifier =
|
||||||
modifier
|
modifier
|
||||||
|
.align(Alignment.TopEnd)
|
||||||
.fillMaxHeight(.85f)
|
.fillMaxHeight(.85f)
|
||||||
.alpha(.75f)
|
.alpha(.75f)
|
||||||
.drawWithContent {
|
.drawWithContent {
|
||||||
|
|
|
||||||
|
|
@ -23,40 +23,65 @@ import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.shape.CircleShape
|
import androidx.compose.foundation.shape.CircleShape
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.text.TextStyle
|
import androidx.compose.ui.text.TextStyle
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.tv.material3.LocalTextStyle
|
||||||
import androidx.tv.material3.MaterialTheme
|
import androidx.tv.material3.MaterialTheme
|
||||||
import androidx.tv.material3.Text
|
import androidx.tv.material3.Text
|
||||||
|
import com.github.damontecres.wholphin.ui.PreviewTvSpec
|
||||||
|
import com.github.damontecres.wholphin.ui.theme.WholphinTheme
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun DotSeparatedRow(
|
fun DotSeparatedRow(
|
||||||
texts: List<String>,
|
texts: List<String>,
|
||||||
|
rating: Float? = null,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
textStyle: TextStyle = MaterialTheme.typography.titleSmall,
|
textStyle: TextStyle = MaterialTheme.typography.titleSmall,
|
||||||
) {
|
) {
|
||||||
Row(
|
CompositionLocalProvider(LocalTextStyle provides textStyle) {
|
||||||
modifier = modifier,
|
Row(
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
modifier = modifier,
|
||||||
) {
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
texts.forEachIndexed { index, text ->
|
) {
|
||||||
Text(
|
texts.forEachIndexed { index, text ->
|
||||||
text = text,
|
Text(
|
||||||
style = textStyle,
|
text = text,
|
||||||
color = MaterialTheme.colorScheme.onSurface,
|
style = textStyle,
|
||||||
)
|
color = MaterialTheme.colorScheme.onSurface,
|
||||||
if (index != texts.lastIndex) {
|
)
|
||||||
Box(
|
if (rating != null || index != texts.lastIndex) {
|
||||||
modifier =
|
Box(
|
||||||
Modifier
|
modifier =
|
||||||
.padding(horizontal = 8.dp)
|
Modifier
|
||||||
.clip(CircleShape)
|
.padding(horizontal = 8.dp)
|
||||||
.background(MaterialTheme.colorScheme.onSurface.copy(alpha = 1f))
|
.clip(CircleShape)
|
||||||
.size(4.dp),
|
.background(MaterialTheme.colorScheme.onSurface.copy(alpha = 1f))
|
||||||
|
.size(4.dp),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rating?.let {
|
||||||
|
SimpleStarRating(
|
||||||
|
communityRating = it,
|
||||||
|
modifier = Modifier,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PreviewTvSpec
|
||||||
|
@Composable
|
||||||
|
private fun DotSeparatedRowPreview() {
|
||||||
|
WholphinTheme {
|
||||||
|
DotSeparatedRow(
|
||||||
|
texts = listOf("2025", "1h 48m", "PG-13", "1h 30m left"),
|
||||||
|
rating = 7.5f,
|
||||||
|
modifier = Modifier,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Star
|
import androidx.compose.material.icons.filled.Star
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableIntStateOf
|
import androidx.compose.runtime.mutableIntStateOf
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
|
@ -36,7 +37,6 @@ import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.unit.Dp
|
import androidx.compose.ui.unit.Dp
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
|
||||||
import androidx.tv.material3.Icon
|
import androidx.tv.material3.Icon
|
||||||
import androidx.tv.material3.LocalContentColor
|
import androidx.tv.material3.LocalContentColor
|
||||||
import androidx.tv.material3.MaterialTheme
|
import androidx.tv.material3.MaterialTheme
|
||||||
|
|
@ -77,17 +77,17 @@ val ratingBarHeight: Dp = 32.dp
|
||||||
fun SimpleStarRating(
|
fun SimpleStarRating(
|
||||||
communityRating: Float?,
|
communityRating: Float?,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) = SimpleStarRating(
|
) = CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onSurface) {
|
||||||
text = communityRating?.let { String.format(Locale.getDefault(), "%.1f", it) },
|
SimpleStarRating(
|
||||||
modifier = modifier,
|
text = communityRating?.let { String.format(Locale.getDefault(), "%.1f", it) },
|
||||||
textColor = MaterialTheme.colorScheme.onSurface,
|
modifier = modifier,
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun SimpleStarRating(
|
fun SimpleStarRating(
|
||||||
text: String?,
|
text: String?,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
textColor: Color = LocalContentColor.current,
|
|
||||||
starColor: Color = FilledStarColor,
|
starColor: Color = FilledStarColor,
|
||||||
) {
|
) {
|
||||||
Row(
|
Row(
|
||||||
|
|
@ -98,8 +98,6 @@ fun SimpleStarRating(
|
||||||
if (text.isNotNullOrBlank()) {
|
if (text.isNotNullOrBlank()) {
|
||||||
Text(
|
Text(
|
||||||
text = text,
|
text = text,
|
||||||
fontSize = 14.sp,
|
|
||||||
color = textColor,
|
|
||||||
modifier = Modifier,
|
modifier = Modifier,
|
||||||
)
|
)
|
||||||
Icon(
|
Icon(
|
||||||
|
|
|
||||||
|
|
@ -197,7 +197,7 @@ fun StreamLabel(
|
||||||
modifier =
|
modifier =
|
||||||
modifier
|
modifier
|
||||||
.background(
|
.background(
|
||||||
MaterialTheme.colorScheme.secondaryContainer,
|
MaterialTheme.colorScheme.secondaryContainer.copy(alpha = .5f),
|
||||||
// MaterialTheme.colorScheme.surfaceVariant,
|
// MaterialTheme.colorScheme.surfaceVariant,
|
||||||
shape = RoundedCornerShape(4.dp),
|
shape = RoundedCornerShape(4.dp),
|
||||||
).padding(vertical = 4.dp, horizontal = 6.dp),
|
).padding(vertical = 4.dp, horizontal = 6.dp),
|
||||||
|
|
@ -245,8 +245,8 @@ private fun StreamLabelPreview() {
|
||||||
.padding(8.dp),
|
.padding(8.dp),
|
||||||
) {
|
) {
|
||||||
StreamLabel("1080p")
|
StreamLabel("1080p")
|
||||||
StreamLabel("H264")
|
|
||||||
StreamLabel("HDR")
|
StreamLabel("HDR")
|
||||||
|
StreamLabel("H264")
|
||||||
StreamLabel("AC3 5.1", icon = R.string.fa_volume_high, count = 2)
|
StreamLabel("AC3 5.1", icon = R.string.fa_volume_high, count = 2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.LazyRow
|
import androidx.compose.foundation.lazy.LazyRow
|
||||||
import androidx.compose.foundation.lazy.itemsIndexed
|
import androidx.compose.foundation.lazy.itemsIndexed
|
||||||
|
|
@ -61,7 +62,6 @@ import com.github.damontecres.wholphin.ui.components.ErrorMessage
|
||||||
import com.github.damontecres.wholphin.ui.components.ExpandablePlayButtons
|
import com.github.damontecres.wholphin.ui.components.ExpandablePlayButtons
|
||||||
import com.github.damontecres.wholphin.ui.components.LoadingPage
|
import com.github.damontecres.wholphin.ui.components.LoadingPage
|
||||||
import com.github.damontecres.wholphin.ui.components.Optional
|
import com.github.damontecres.wholphin.ui.components.Optional
|
||||||
import com.github.damontecres.wholphin.ui.components.VideoStreamDetails
|
|
||||||
import com.github.damontecres.wholphin.ui.components.chooseStream
|
import com.github.damontecres.wholphin.ui.components.chooseStream
|
||||||
import com.github.damontecres.wholphin.ui.components.chooseVersionParams
|
import com.github.damontecres.wholphin.ui.components.chooseVersionParams
|
||||||
import com.github.damontecres.wholphin.ui.data.AddPlaylistViewModel
|
import com.github.damontecres.wholphin.ui.data.AddPlaylistViewModel
|
||||||
|
|
@ -391,7 +391,6 @@ fun MovieDetailsContent(
|
||||||
Modifier
|
Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.bringIntoViewRequester(bringIntoViewRequester),
|
.bringIntoViewRequester(bringIntoViewRequester),
|
||||||
// .padding(bottom = 16.dp),
|
|
||||||
) {
|
) {
|
||||||
MovieDetailsHeader(
|
MovieDetailsHeader(
|
||||||
preferences = preferences,
|
preferences = preferences,
|
||||||
|
|
@ -399,7 +398,10 @@ fun MovieDetailsContent(
|
||||||
chosenStreams = chosenStreams,
|
chosenStreams = chosenStreams,
|
||||||
bringIntoViewRequester = bringIntoViewRequester,
|
bringIntoViewRequester = bringIntoViewRequester,
|
||||||
overviewOnClick = overviewOnClick,
|
overviewOnClick = overviewOnClick,
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier =
|
||||||
|
Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(top = 32.dp, bottom = 16.dp),
|
||||||
)
|
)
|
||||||
ExpandablePlayButtons(
|
ExpandablePlayButtons(
|
||||||
resumePosition = resumePosition,
|
resumePosition = resumePosition,
|
||||||
|
|
@ -420,18 +422,13 @@ fun MovieDetailsContent(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
modifier = Modifier.focusRequester(focusRequesters[HEADER_ROW]),
|
modifier =
|
||||||
|
Modifier
|
||||||
|
.padding(bottom = 16.dp)
|
||||||
|
.focusRequester(focusRequesters[HEADER_ROW]),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
item {
|
|
||||||
VideoStreamDetails(
|
|
||||||
preferences = preferences,
|
|
||||||
dto = dto,
|
|
||||||
itemPlayback = chosenStreams?.itemPlayback,
|
|
||||||
modifier = Modifier,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if (people.isNotEmpty()) {
|
if (people.isNotEmpty()) {
|
||||||
item {
|
item {
|
||||||
PersonRow(
|
PersonRow(
|
||||||
|
|
|
||||||
|
|
@ -4,18 +4,17 @@ import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
import androidx.compose.foundation.interaction.collectIsFocusedAsState
|
import androidx.compose.foundation.interaction.collectIsFocusedAsState
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.relocation.BringIntoViewRequester
|
import androidx.compose.foundation.relocation.BringIntoViewRequester
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.text.font.FontStyle
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.unit.Dp
|
import androidx.compose.ui.unit.Dp
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
|
@ -27,7 +26,7 @@ import com.github.damontecres.wholphin.data.model.BaseItem
|
||||||
import com.github.damontecres.wholphin.preferences.UserPreferences
|
import com.github.damontecres.wholphin.preferences.UserPreferences
|
||||||
import com.github.damontecres.wholphin.ui.components.DotSeparatedRow
|
import com.github.damontecres.wholphin.ui.components.DotSeparatedRow
|
||||||
import com.github.damontecres.wholphin.ui.components.OverviewText
|
import com.github.damontecres.wholphin.ui.components.OverviewText
|
||||||
import com.github.damontecres.wholphin.ui.components.SimpleStarRating
|
import com.github.damontecres.wholphin.ui.components.VideoStreamDetails
|
||||||
import com.github.damontecres.wholphin.ui.isNotNullOrBlank
|
import com.github.damontecres.wholphin.ui.isNotNullOrBlank
|
||||||
import com.github.damontecres.wholphin.ui.roundMinutes
|
import com.github.damontecres.wholphin.ui.roundMinutes
|
||||||
import com.github.damontecres.wholphin.ui.timeRemaining
|
import com.github.damontecres.wholphin.ui.timeRemaining
|
||||||
|
|
@ -54,51 +53,49 @@ fun MovieDetailsHeader(
|
||||||
Text(
|
Text(
|
||||||
text = movie.name ?: "",
|
text = movie.name ?: "",
|
||||||
color = MaterialTheme.colorScheme.onSurface,
|
color = MaterialTheme.colorScheme.onSurface,
|
||||||
style = MaterialTheme.typography.displayMedium,
|
style = MaterialTheme.typography.displaySmall,
|
||||||
maxLines = 2,
|
maxLines = 2,
|
||||||
overflow = TextOverflow.Ellipsis,
|
overflow = TextOverflow.Ellipsis,
|
||||||
modifier = Modifier.fillMaxWidth(.75f),
|
modifier = Modifier.fillMaxWidth(.75f),
|
||||||
)
|
)
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
verticalArrangement = Arrangement.spacedBy(4.dp),
|
||||||
modifier = Modifier.fillMaxWidth(.60f),
|
modifier = Modifier.fillMaxWidth(.60f),
|
||||||
) {
|
) {
|
||||||
Row(
|
val padding = 8.dp
|
||||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
val details =
|
||||||
) {
|
remember(dto) {
|
||||||
val details =
|
|
||||||
buildList {
|
buildList {
|
||||||
dto.productionYear?.let { add(it.toString()) }
|
dto.productionYear?.let { add(it.toString()) }
|
||||||
val duration = dto.runTimeTicks?.ticks
|
val duration = dto.runTimeTicks?.ticks
|
||||||
duration
|
duration
|
||||||
?.roundMinutes
|
?.roundMinutes
|
||||||
?.toString()
|
?.toString()
|
||||||
?.let {
|
?.let(::add)
|
||||||
add(it)
|
|
||||||
}
|
|
||||||
dto.officialRating?.let(::add)
|
|
||||||
dto.timeRemaining?.roundMinutes?.let { add("$it left") }
|
dto.timeRemaining?.roundMinutes?.let { add("$it left") }
|
||||||
|
dto.officialRating?.let(::add)
|
||||||
}
|
}
|
||||||
DotSeparatedRow(
|
}
|
||||||
texts = details,
|
DotSeparatedRow(
|
||||||
textStyle = MaterialTheme.typography.titleMedium,
|
texts = details,
|
||||||
modifier = Modifier,
|
rating = dto.communityRating,
|
||||||
)
|
textStyle = MaterialTheme.typography.titleMedium,
|
||||||
}
|
modifier = Modifier.padding(bottom = padding),
|
||||||
Row(
|
)
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
|
||||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
VideoStreamDetails(
|
||||||
) {
|
preferences = preferences,
|
||||||
SimpleStarRating(
|
dto = dto,
|
||||||
dto.communityRating,
|
itemPlayback = chosenStreams?.itemPlayback,
|
||||||
Modifier.height(20.dp),
|
modifier = Modifier.padding(bottom = padding),
|
||||||
)
|
)
|
||||||
}
|
|
||||||
dto.taglines?.firstOrNull()?.let { tagline ->
|
dto.taglines?.firstOrNull()?.let { tagline ->
|
||||||
Text(
|
Text(
|
||||||
text = tagline,
|
text = tagline,
|
||||||
style = MaterialTheme.typography.bodyLarge,
|
style = MaterialTheme.typography.bodyLarge,
|
||||||
|
fontStyle = FontStyle.Italic,
|
||||||
|
modifier = Modifier,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@ import com.github.damontecres.wholphin.data.ChosenStreams
|
||||||
import com.github.damontecres.wholphin.data.model.BaseItem
|
import com.github.damontecres.wholphin.data.model.BaseItem
|
||||||
import com.github.damontecres.wholphin.preferences.UserPreferences
|
import com.github.damontecres.wholphin.preferences.UserPreferences
|
||||||
import com.github.damontecres.wholphin.ui.components.ExpandablePlayButtons
|
import com.github.damontecres.wholphin.ui.components.ExpandablePlayButtons
|
||||||
import com.github.damontecres.wholphin.ui.components.VideoStreamDetails
|
|
||||||
import org.jellyfin.sdk.model.extensions.ticks
|
import org.jellyfin.sdk.model.extensions.ticks
|
||||||
import kotlin.time.Duration
|
import kotlin.time.Duration
|
||||||
|
|
||||||
|
|
@ -45,11 +44,5 @@ fun FocusedEpisodeFooter(
|
||||||
buttonOnFocusChanged = {},
|
buttonOnFocusChanged = {},
|
||||||
modifier = Modifier,
|
modifier = Modifier,
|
||||||
)
|
)
|
||||||
VideoStreamDetails(
|
|
||||||
preferences = preferences,
|
|
||||||
dto = dto,
|
|
||||||
itemPlayback = chosenStreams?.itemPlayback,
|
|
||||||
modifier = Modifier,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,8 @@ package com.github.damontecres.wholphin.ui.detail.series
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
|
||||||
import androidx.compose.foundation.layout.height
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
|
|
@ -17,7 +15,7 @@ import com.github.damontecres.wholphin.data.model.BaseItem
|
||||||
import com.github.damontecres.wholphin.preferences.UserPreferences
|
import com.github.damontecres.wholphin.preferences.UserPreferences
|
||||||
import com.github.damontecres.wholphin.ui.components.DotSeparatedRow
|
import com.github.damontecres.wholphin.ui.components.DotSeparatedRow
|
||||||
import com.github.damontecres.wholphin.ui.components.OverviewText
|
import com.github.damontecres.wholphin.ui.components.OverviewText
|
||||||
import com.github.damontecres.wholphin.ui.components.SimpleStarRating
|
import com.github.damontecres.wholphin.ui.components.VideoStreamDetails
|
||||||
import com.github.damontecres.wholphin.ui.formatDateTime
|
import com.github.damontecres.wholphin.ui.formatDateTime
|
||||||
import com.github.damontecres.wholphin.ui.roundMinutes
|
import com.github.damontecres.wholphin.ui.roundMinutes
|
||||||
import com.github.damontecres.wholphin.ui.seasonEpisode
|
import com.github.damontecres.wholphin.ui.seasonEpisode
|
||||||
|
|
@ -45,10 +43,8 @@ fun FocusedEpisodeHeader(
|
||||||
overflow = TextOverflow.Ellipsis,
|
overflow = TextOverflow.Ellipsis,
|
||||||
modifier = Modifier,
|
modifier = Modifier,
|
||||||
)
|
)
|
||||||
Row(
|
val details =
|
||||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
remember(dto) {
|
||||||
) {
|
|
||||||
val details =
|
|
||||||
buildList {
|
buildList {
|
||||||
dto?.seasonEpisode?.let(::add)
|
dto?.seasonEpisode?.let(::add)
|
||||||
dto?.premiereDate?.let { add(formatDateTime(it)) }
|
dto?.premiereDate?.let { add(formatDateTime(it)) }
|
||||||
|
|
@ -56,24 +52,23 @@ fun FocusedEpisodeHeader(
|
||||||
duration
|
duration
|
||||||
?.roundMinutes
|
?.roundMinutes
|
||||||
?.toString()
|
?.toString()
|
||||||
?.let {
|
?.let(::add)
|
||||||
add(it)
|
|
||||||
}
|
|
||||||
dto?.officialRating?.let(::add)
|
|
||||||
dto?.timeRemaining?.roundMinutes?.let { add("$it left") }
|
dto?.timeRemaining?.roundMinutes?.let { add("$it left") }
|
||||||
|
dto?.officialRating?.let(::add)
|
||||||
}
|
}
|
||||||
DotSeparatedRow(
|
}
|
||||||
texts = details,
|
DotSeparatedRow(
|
||||||
textStyle = MaterialTheme.typography.titleSmall,
|
texts = details,
|
||||||
)
|
rating = dto?.communityRating,
|
||||||
}
|
textStyle = MaterialTheme.typography.titleSmall,
|
||||||
Row(
|
)
|
||||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
if (dto != null) {
|
||||||
) {
|
VideoStreamDetails(
|
||||||
SimpleStarRating(
|
preferences = preferences,
|
||||||
dto?.communityRating,
|
dto = dto,
|
||||||
Modifier.height(20.dp),
|
itemPlayback = chosenStreams?.itemPlayback,
|
||||||
|
modifier = Modifier,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
OverviewText(
|
OverviewText(
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.relocation.BringIntoViewRequester
|
import androidx.compose.foundation.relocation.BringIntoViewRequester
|
||||||
|
|
@ -30,6 +29,7 @@ import androidx.compose.ui.focus.onFocusChanged
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.unit.Dp
|
import androidx.compose.ui.unit.Dp
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
||||||
|
|
@ -60,7 +60,6 @@ import com.github.damontecres.wholphin.ui.components.ExpandablePlayButton
|
||||||
import com.github.damontecres.wholphin.ui.components.LoadingPage
|
import com.github.damontecres.wholphin.ui.components.LoadingPage
|
||||||
import com.github.damontecres.wholphin.ui.components.Optional
|
import com.github.damontecres.wholphin.ui.components.Optional
|
||||||
import com.github.damontecres.wholphin.ui.components.OverviewText
|
import com.github.damontecres.wholphin.ui.components.OverviewText
|
||||||
import com.github.damontecres.wholphin.ui.components.SimpleStarRating
|
|
||||||
import com.github.damontecres.wholphin.ui.data.AddPlaylistViewModel
|
import com.github.damontecres.wholphin.ui.data.AddPlaylistViewModel
|
||||||
import com.github.damontecres.wholphin.ui.data.ItemDetailsDialog
|
import com.github.damontecres.wholphin.ui.data.ItemDetailsDialog
|
||||||
import com.github.damontecres.wholphin.ui.data.ItemDetailsDialogInfo
|
import com.github.damontecres.wholphin.ui.data.ItemDetailsDialogInfo
|
||||||
|
|
@ -584,23 +583,18 @@ fun SeriesDetailsHeader(
|
||||||
)
|
)
|
||||||
DotSeparatedRow(
|
DotSeparatedRow(
|
||||||
texts = details,
|
texts = details,
|
||||||
|
rating = dto.communityRating,
|
||||||
textStyle = MaterialTheme.typography.titleMedium,
|
textStyle = MaterialTheme.typography.titleMedium,
|
||||||
)
|
)
|
||||||
|
|
||||||
dto.genres?.letNotEmpty {
|
dto.genres?.letNotEmpty {
|
||||||
Text(
|
Text(
|
||||||
text = it.joinToString(", "),
|
text = it.joinToString(", "),
|
||||||
style = MaterialTheme.typography.bodyLarge,
|
style = MaterialTheme.typography.bodyLarge,
|
||||||
color = MaterialTheme.colorScheme.onSurface,
|
color = MaterialTheme.colorScheme.onSurface,
|
||||||
|
overflow = TextOverflow.Ellipsis,
|
||||||
modifier = Modifier,
|
modifier = Modifier,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleStarRating(
|
|
||||||
dto.communityRating,
|
|
||||||
Modifier.height(20.dp),
|
|
||||||
)
|
|
||||||
|
|
||||||
dto.overview?.let { overview ->
|
dto.overview?.let { overview ->
|
||||||
OverviewText(
|
OverviewText(
|
||||||
overview = overview,
|
overview = overview,
|
||||||
|
|
|
||||||
|
|
@ -502,6 +502,7 @@ fun HomePageHeader(
|
||||||
if (details.isNotEmpty()) {
|
if (details.isNotEmpty()) {
|
||||||
DotSeparatedRow(
|
DotSeparatedRow(
|
||||||
texts = details,
|
texts = details,
|
||||||
|
rating = item.data.communityRating,
|
||||||
textStyle = MaterialTheme.typography.bodyLarge,
|
textStyle = MaterialTheme.typography.bodyLarge,
|
||||||
modifier = Modifier,
|
modifier = Modifier,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue