mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-05-04 17:29:07 +00:00
feat: add runtime formatting
This commit is contained in:
parent
2f74c3cab0
commit
81cd7933eb
4 changed files with 52 additions and 10 deletions
|
|
@ -0,0 +1,46 @@
|
|||
package com.nuvio.app.features.details
|
||||
|
||||
private val hourTokenRegex = Regex("""(?i)(\d+)\s*h(?:ours?)?""")
|
||||
private val minuteTokenRegex = Regex("""(?i)(\d+)\s*m(?:in(?:ute)?s?)?""")
|
||||
private val hourMinuteColonRegex = Regex("""^\s*(\d+)\s*:\s*(\d{1,2})\s*$""")
|
||||
private val digitsOnlyRegex = Regex("""^\s*(\d+)\s*$""")
|
||||
|
||||
internal fun formatRuntimeForDisplay(rawRuntime: String?): String? {
|
||||
val normalized = rawRuntime?.trim()?.takeIf { it.isNotBlank() } ?: return null
|
||||
val totalMinutes = parseRuntimeMinutes(normalized) ?: return normalized
|
||||
return formatRuntimeFromMinutes(totalMinutes)
|
||||
}
|
||||
|
||||
internal fun formatRuntimeFromMinutes(totalMinutes: Int): String {
|
||||
if (totalMinutes <= 0) return ""
|
||||
val hours = totalMinutes / 60
|
||||
val minutes = totalMinutes % 60
|
||||
|
||||
return when {
|
||||
hours > 0 && minutes > 0 -> "${hours}h ${minutes}m"
|
||||
hours > 0 -> "${hours}h"
|
||||
else -> "${minutes}m"
|
||||
}
|
||||
}
|
||||
|
||||
private fun parseRuntimeMinutes(value: String): Int? {
|
||||
hourMinuteColonRegex.matchEntire(value)?.let { match ->
|
||||
val hours = match.groupValues[1].toIntOrNull() ?: return null
|
||||
val minutes = match.groupValues[2].toIntOrNull() ?: return null
|
||||
return (hours * 60) + minutes
|
||||
}
|
||||
|
||||
val hoursToken = hourTokenRegex.find(value)?.groupValues?.getOrNull(1)?.toIntOrNull()
|
||||
val minutesToken = minuteTokenRegex.find(value)?.groupValues?.getOrNull(1)?.toIntOrNull()
|
||||
if (hoursToken != null || minutesToken != null) {
|
||||
val hours = (hoursToken ?: 0).coerceAtLeast(0)
|
||||
val minutes = (minutesToken ?: 0).coerceAtLeast(0)
|
||||
return (hours * 60) + minutes
|
||||
}
|
||||
|
||||
digitsOnlyRegex.matchEntire(value)?.let { match ->
|
||||
return match.groupValues[1].toIntOrNull()?.coerceAtLeast(0)
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
|
@ -18,6 +18,7 @@ import androidx.compose.ui.text.style.TextOverflow
|
|||
import androidx.compose.ui.unit.dp
|
||||
import com.nuvio.app.core.format.formatReleaseDateForDisplay
|
||||
import com.nuvio.app.features.details.MetaDetails
|
||||
import com.nuvio.app.features.details.formatRuntimeForDisplay
|
||||
|
||||
@Composable
|
||||
fun DetailAdditionalInfoSection(
|
||||
|
|
@ -30,7 +31,7 @@ fun DetailAdditionalInfoSection(
|
|||
val rows = buildList {
|
||||
meta.status?.let { add("Status" to it) }
|
||||
meta.releaseInfo?.let { add("Release Info" to formatReleaseDateForDisplay(it)) }
|
||||
meta.runtime?.let { add("Runtime" to it.uppercase()) }
|
||||
formatRuntimeForDisplay(meta.runtime)?.let { add("Runtime" to it) }
|
||||
meta.ageRating?.let { add("Certification" to it) }
|
||||
meta.country?.let { add("Origin Country" to it) }
|
||||
meta.language?.let { add("Original Language" to it.uppercase()) }
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ import androidx.compose.ui.unit.dp
|
|||
import androidx.compose.ui.unit.sp
|
||||
import com.nuvio.app.features.details.MetaDetails
|
||||
import com.nuvio.app.features.details.MetaExternalRating
|
||||
import com.nuvio.app.features.details.formatRuntimeForDisplay
|
||||
import com.nuvio.app.features.details.formatMetaReleaseLineForDetails
|
||||
import com.nuvio.app.features.mdblist.MdbListMetadataService.PROVIDER_AUDIENCE
|
||||
import com.nuvio.app.features.mdblist.MdbListMetadataService.PROVIDER_IMDB
|
||||
|
|
@ -73,7 +74,7 @@ fun DetailMetaInfo(
|
|||
verticalArrangement = Arrangement.spacedBy(12.dp),
|
||||
) {
|
||||
val releaseLine = formatMetaReleaseLineForDetails(meta)
|
||||
val runtimeText = meta.runtime?.trim()?.takeIf { it.isNotBlank() }?.uppercase()
|
||||
val runtimeText = formatRuntimeForDisplay(meta.runtime)
|
||||
val ageBadge = meta.ageRating?.trim()?.takeIf { it.isNotBlank() }
|
||||
val hasMdbImdbRating = meta.externalRatings.any { it.source == PROVIDER_IMDB }
|
||||
val hasMetaRow = releaseLine != null ||
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ import com.nuvio.app.features.details.MetaEpisodeCardStyle
|
|||
import com.nuvio.app.features.details.MetaVideo
|
||||
import com.nuvio.app.features.details.SeasonViewMode
|
||||
import com.nuvio.app.features.details.SeasonViewModeStorage
|
||||
import com.nuvio.app.features.details.formatRuntimeFromMinutes
|
||||
import com.nuvio.app.features.details.metaVideoSeasonEpisodeComparator
|
||||
import com.nuvio.app.features.details.normalizeSeasonNumber
|
||||
import com.nuvio.app.features.details.seasonSortKey
|
||||
|
|
@ -843,14 +844,7 @@ private fun rememberEpisodeHorizontalCardMetrics(maxWidthDp: Float): EpisodeHori
|
|||
}
|
||||
|
||||
private fun formatEpisodeRuntime(runtimeMinutes: Int): String {
|
||||
if (runtimeMinutes <= 0) return ""
|
||||
val hours = runtimeMinutes / 60
|
||||
val minutes = runtimeMinutes % 60
|
||||
return when {
|
||||
hours > 0 && minutes > 0 -> "${hours}h ${minutes}m"
|
||||
hours > 0 -> "${hours}h"
|
||||
else -> "${minutes}m"
|
||||
}
|
||||
return formatRuntimeFromMinutes(runtimeMinutes)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
|
|
|
|||
Loading…
Reference in a new issue