feat: add MediaProgressBar component and integrate into SeriesComponents for episode progress display

This commit is contained in:
2026-02-04 14:20:34 +01:00
parent 0ebd5c5afe
commit 4300c8ce84
3 changed files with 69 additions and 23 deletions

View File

@@ -50,6 +50,7 @@ import hu.bbara.purefin.common.ui.MediaCastRow
import hu.bbara.purefin.common.ui.MediaMetaChip
import hu.bbara.purefin.common.ui.components.GhostIconButton
import hu.bbara.purefin.common.ui.components.MediaActionButton
import hu.bbara.purefin.common.ui.components.MediaProgressBar
import hu.bbara.purefin.common.ui.components.PurefinAsyncImage
import hu.bbara.purefin.common.ui.components.WatchStateIndicator
import hu.bbara.purefin.data.model.CastMember
@@ -255,6 +256,13 @@ private fun EpisodeCard(
fontWeight = FontWeight.Bold
)
}
if (episode.watched.not() && (episode.progress ?: 0.0) > 0) {
MediaProgressBar(
progress = (episode.progress ?: 0.0).toFloat().div(100),
modifier = Modifier
.align(Alignment.BottomStart)
)
} else {
WatchStateIndicator(
watched = episode.watched,
started = (episode.progress ?: 0.0) > 0.0,
@@ -263,6 +271,7 @@ private fun EpisodeCard(
.padding(8.dp)
)
}
}
Column(
) {
Text(

View File

@@ -10,10 +10,8 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
@@ -42,6 +40,7 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import coil3.request.ImageRequest
import hu.bbara.purefin.common.ui.PosterCard
import hu.bbara.purefin.common.ui.components.MediaProgressBar
import hu.bbara.purefin.common.ui.components.PurefinAsyncImage
import hu.bbara.purefin.player.PlayerActivity
import org.jellyfin.sdk.model.UUID
@@ -136,22 +135,13 @@ fun ContinueWatchingCard(
},
contentScale = ContentScale.Crop,
)
Box(
MediaProgressBar(
progress = item.progress.toFloat().nextUp().div(100),
foregroundColor = scheme.onSurface,
backgroundColor = scheme.primary,
modifier = Modifier
.align(Alignment.BottomStart)
.padding(bottom = 8.dp, start = 8.dp, end = 8.dp)
.clip(RoundedCornerShape(24.dp))
.fillMaxWidth()
.height(4.dp)
.background(scheme.onBackground.copy(alpha = 0.2f))
) {
Box(
modifier = Modifier
.fillMaxHeight()
.fillMaxWidth(item.progress.toFloat().nextUp().div(100))
.background(scheme.primary)
)
}
IconButton(
modifier = Modifier
.align(Alignment.BottomEnd)

View File

@@ -0,0 +1,47 @@
package hu.bbara.purefin.common.ui.components
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
/**
* A progress bar component for displaying media playback progress.
*
* @param progress The progress value between 0f and 1f, where 0f is no progress and 1f is complete.
* @param foregroundColor The color of the progress indicator.
* @param backgroundColor The color of the background/unfilled portion of the progress bar.
* @param modifier The modifier to be applied to the Box. Modifier should contain the Alignment.
*/
@Composable
fun MediaProgressBar(
progress: Float,
foregroundColor: Color = MaterialTheme.colorScheme.onSurface,
backgroundColor: Color = MaterialTheme.colorScheme.primary,
modifier: Modifier
) {
Box(
modifier = modifier
.padding(bottom = 8.dp, start = 8.dp, end = 8.dp)
.clip(RoundedCornerShape(24.dp))
.fillMaxWidth()
.height(4.dp)
.background(backgroundColor.copy(alpha = 0.2f))
) {
Box(
modifier = Modifier
.fillMaxHeight()
.fillMaxWidth(progress)
.background(foregroundColor)
)
}
}