Better formatting

This commit is contained in:
Damontecres 2025-10-06 14:26:26 -04:00
parent 73bb96adfb
commit ead2431bc4
No known key found for this signature in database
7 changed files with 54 additions and 26 deletions

View file

@ -47,6 +47,7 @@ import com.github.damontecres.dolphin.data.model.BaseItem
import com.github.damontecres.dolphin.ui.FontAwesome import com.github.damontecres.dolphin.ui.FontAwesome
import com.github.damontecres.dolphin.ui.enableMarquee import com.github.damontecres.dolphin.ui.enableMarquee
import com.github.damontecres.dolphin.ui.ifElse import com.github.damontecres.dolphin.ui.ifElse
import com.github.damontecres.dolphin.util.seasonEpisode
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import org.jellyfin.sdk.model.api.BaseItemKind import org.jellyfin.sdk.model.api.BaseItemKind
@ -138,9 +139,9 @@ fun ItemCard(
) )
} }
if (dto.type == BaseItemKind.EPISODE) { if (dto.type == BaseItemKind.EPISODE) {
if (dto.parentIndexNumber != null && dto.indexNumber != null) { dto.seasonEpisode?.let {
Text( Text(
text = "S${dto.parentIndexNumber} E${dto.indexNumber}", text = it,
) )
} }
} }

View file

@ -35,6 +35,7 @@ import com.github.damontecres.dolphin.ui.isNotNullOrBlank
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
import com.github.damontecres.dolphin.util.LoadingState import com.github.damontecres.dolphin.util.LoadingState
import com.github.damontecres.dolphin.util.seasonEpisode
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
import org.jellyfin.sdk.api.client.ApiClient import org.jellyfin.sdk.api.client.ApiClient
import org.jellyfin.sdk.model.api.ImageType import org.jellyfin.sdk.model.api.ImageType
@ -100,9 +101,7 @@ fun EpisodeDetailsContent(
val details = val details =
buildList { buildList {
if (dto.parentIndexNumber != null && dto.indexNumber != null) { dto.seasonEpisode?.let(::add)
add("S${dto.parentIndexNumber} E${dto.indexNumber}")
}
dto.mediaSources?.firstOrNull()?.runTimeTicks?.ticks?.inWholeMinutes?.toString()?.let { dto.mediaSources?.firstOrNull()?.runTimeTicks?.ticks?.inWholeMinutes?.toString()?.let {
add(it) add(it)
} }

View file

@ -32,6 +32,7 @@ import com.github.damontecres.dolphin.ui.playSoundOnFocus
import com.github.damontecres.dolphin.ui.roundMinutes import com.github.damontecres.dolphin.ui.roundMinutes
import com.github.damontecres.dolphin.ui.timeRemaining import com.github.damontecres.dolphin.ui.timeRemaining
import com.github.damontecres.dolphin.util.formatDateTime import com.github.damontecres.dolphin.util.formatDateTime
import com.github.damontecres.dolphin.util.seasonEpisode
import org.jellyfin.sdk.model.extensions.ticks import org.jellyfin.sdk.model.extensions.ticks
@Composable @Composable
@ -56,9 +57,7 @@ fun FocusedEpisodeHeader(
) { ) {
val details = val details =
buildList { buildList {
if (dto.parentIndexNumber != null && dto.indexNumber != null) { dto.seasonEpisode?.let(::add)
add("S${dto.parentIndexNumber} E${dto.indexNumber}")
}
dto.premiereDate?.let { add(formatDateTime(it)) } dto.premiereDate?.let { add(formatDateTime(it)) }
val duration = dto.runTimeTicks?.ticks val duration = dto.runTimeTicks?.ticks
duration duration

View file

@ -1,6 +1,7 @@
package com.github.damontecres.dolphin.ui.playback package com.github.damontecres.dolphin.ui.playback
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
@ -50,6 +51,7 @@ fun NextUpEpisode(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
aspectRatio: Float = 16f / 9, aspectRatio: Float = 16f / 9,
) { ) {
val interactionSource = remember { MutableInteractionSource() }
val focusRequester = remember { FocusRequester() } val focusRequester = remember { FocusRequester() }
LaunchedEffect(Unit) { focusRequester.tryRequestFocus() } LaunchedEffect(Unit) { focusRequester.tryRequestFocus() }
Box( Box(
@ -60,11 +62,11 @@ fun NextUpEpisode(
modifier = modifier =
Modifier Modifier
.fillMaxSize() .fillMaxSize()
.padding(8.dp), .padding(horizontal = 16.dp, vertical = 8.dp),
) { ) {
Text( Text(
text = "Up Next...", text = "Up Next...",
style = MaterialTheme.typography.titleSmall, style = MaterialTheme.typography.titleLarge,
color = MaterialTheme.colorScheme.onSurface, color = MaterialTheme.colorScheme.onSurface,
textAlign = TextAlign.Center, textAlign = TextAlign.Center,
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
@ -78,19 +80,23 @@ fun NextUpEpisode(
imageUrl = imageUrl, imageUrl = imageUrl,
onClick = onClick, onClick = onClick,
timeLeft = timeLeft, timeLeft = timeLeft,
interactionSource = interactionSource,
modifier = modifier =
Modifier Modifier
.fillMaxWidth(.4f) // .fillMaxWidth(.4f)
.fillMaxHeight() // .fillMaxHeight()
.focusRequester(focusRequester), .focusRequester(focusRequester),
) )
Column( Column(
verticalArrangement = Arrangement.spacedBy(8.dp), verticalArrangement = Arrangement.spacedBy(8.dp),
modifier = Modifier.fillMaxHeight(), modifier =
Modifier
.fillMaxHeight()
.weight(1f),
) { ) {
Text( Text(
text = title ?: "", text = title ?: "",
style = MaterialTheme.typography.bodyMedium, style = MaterialTheme.typography.titleMedium,
color = MaterialTheme.colorScheme.onSurface, color = MaterialTheme.colorScheme.onSurface,
maxLines = 1, maxLines = 1,
overflow = TextOverflow.Ellipsis, overflow = TextOverflow.Ellipsis,
@ -98,7 +104,7 @@ fun NextUpEpisode(
) )
Text( Text(
text = description ?: "", text = description ?: "",
style = MaterialTheme.typography.bodySmall, style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurface, color = MaterialTheme.colorScheme.onSurface,
overflow = TextOverflow.Ellipsis, overflow = TextOverflow.Ellipsis,
modifier = Modifier, modifier = Modifier,
@ -114,18 +120,20 @@ fun NextUpCard(
imageUrl: String?, imageUrl: String?,
onClick: () -> Unit, onClick: () -> Unit,
timeLeft: Duration?, timeLeft: Duration?,
interactionSource: MutableInteractionSource,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
) { ) {
Card( Card(
modifier = modifier, modifier = modifier,
onClick = onClick, onClick = onClick,
interactionSource = interactionSource,
) { ) {
Box(modifier = Modifier.fillMaxSize()) { Box(modifier = Modifier) {
AsyncImage( AsyncImage(
model = imageUrl, model = imageUrl,
contentDescription = null, contentDescription = null,
contentScale = ContentScale.Fit, contentScale = ContentScale.Fit,
modifier = Modifier.fillMaxSize(), modifier = Modifier,
) )
if (timeLeft != null && timeLeft > Duration.ZERO) { if (timeLeft != null && timeLeft > Duration.ZERO) {
Box( Box(

View file

@ -62,6 +62,7 @@ import com.github.damontecres.dolphin.ui.components.LoadingPage
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
import com.github.damontecres.dolphin.ui.tryRequestFocus import com.github.damontecres.dolphin.ui.tryRequestFocus
import com.github.damontecres.dolphin.util.seasonEpisode
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import org.jellyfin.sdk.model.api.DeviceProfile import org.jellyfin.sdk.model.api.DeviceProfile
import kotlin.time.Duration.Companion.milliseconds import kotlin.time.Duration.Companion.milliseconds
@ -356,7 +357,11 @@ fun PlaybackContent(
} }
} }
NextUpEpisode( NextUpEpisode(
title = it.name, title =
listOfNotNull(
it.data.seasonEpisode,
it.name,
).joinToString(" - "),
description = it.data.overview, description = it.data.overview,
imageUrl = it.imageUrl, imageUrl = it.imageUrl,
aspectRatio = it.data.primaryImageAspectRatio?.toFloat() ?: (16f / 9), aspectRatio = it.data.primaryImageAspectRatio?.toFloat() ?: (16f / 9),
@ -366,8 +371,8 @@ fun PlaybackContent(
Modifier Modifier
.padding(8.dp) .padding(8.dp)
// .height(128.dp) // .height(128.dp)
.fillMaxHeight(.3f) .fillMaxHeight(.5f)
.fillMaxWidth(.5f) .fillMaxWidth(.66f)
.align(Alignment.BottomCenter) .align(Alignment.BottomCenter)
.background( .background(
MaterialTheme.colorScheme.surfaceColorAtElevation(2.dp), MaterialTheme.colorScheme.surfaceColorAtElevation(2.dp),

View file

@ -26,6 +26,7 @@ import com.github.damontecres.dolphin.util.TrackActivityPlaybackListener
import com.github.damontecres.dolphin.util.TrackSupport import com.github.damontecres.dolphin.util.TrackSupport
import com.github.damontecres.dolphin.util.checkForSupport import com.github.damontecres.dolphin.util.checkForSupport
import com.github.damontecres.dolphin.util.formatDateTime import com.github.damontecres.dolphin.util.formatDateTime
import com.github.damontecres.dolphin.util.seasonEpisodePadded
import com.github.damontecres.dolphin.util.subtitleMimeTypes import com.github.damontecres.dolphin.util.subtitleMimeTypes
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.android.qualifiers.ApplicationContext
@ -126,13 +127,8 @@ class PlaybackViewModel
} }
val subtitle = val subtitle =
if (base.type == BaseItemKind.EPISODE) { if (base.type == BaseItemKind.EPISODE) {
val season = base.parentIndexNumber?.toString()?.padStart(2, '0')
val episode = base.indexNumber?.toString()?.padStart(2, '0')
// TODO multi episode support
buildList { buildList {
if (season != null && episode != null) { add(base.seasonEpisodePadded)
add("S${season}E$episode")
}
add(base.name) add(base.name)
add(base.premiereDate?.let { formatDateTime(it) }) add(base.premiereDate?.let { formatDateTime(it) })
}.filterNotNull().joinToString(" - ") }.filterNotNull().joinToString(" - ")

View file

@ -1,6 +1,7 @@
package com.github.damontecres.dolphin.util package com.github.damontecres.dolphin.util
import android.os.Build import android.os.Build
import org.jellyfin.sdk.model.api.BaseItemDto
import java.time.LocalDateTime import java.time.LocalDateTime
import java.time.format.DateTimeFormatter import java.time.format.DateTimeFormatter
@ -13,3 +14,22 @@ fun formatDateTime(dateTime: LocalDateTime): String =
} else { } else {
dateTime.toString() dateTime.toString()
} }
// TODO multi episode support
val BaseItemDto.seasonEpisode: String?
get() =
if (parentIndexNumber != null && indexNumber != null) {
"S$parentIndexNumber E$indexNumber"
} else {
null
}
val BaseItemDto.seasonEpisodePadded: String?
get() =
if (parentIndexNumber != null && indexNumber != null) {
val season = parentIndexNumber?.toString()?.padStart(2, '0')
val episode = indexNumber?.toString()?.padStart(2, '0')
"S${season}E$episode"
} else {
null
}