mirror of
https://github.com/bbara04/Purefin.git
synced 2026-03-31 17:10:08 +02:00
feat: use MediaResumeButton with progress in Movie and Episode screens
Replace MediaPlayButton with MediaResumeButton in both MovieComponents and EpisodeComponents, converting Double progress (0-100) to Float (0-1).
This commit is contained in:
@@ -135,6 +135,7 @@ object ContentMockData {
|
|||||||
heroImageUrl = "https://lh3.googleusercontent.com/aida-public/AB6AXuD3hBjDpw00tDCQsK5xNcnJra301k1T4LksWVZzHieH9KHQItEQkVzhwevJvf8RkaQKdVKvObzRlfDDqa3_PNwLUlUQc1LpDih8p94VTGobEV62qi7QrmNyQm_o55KRMNWiTG3zLLpblGqo3uUNQcYmPFqfNML95dClXQ4lQNl85-zgerPPAbGPr23dswbIYCigyTAaXgrmdV_nbNQ5LdDB0Wh5cMHtP0uxz6k3ARjNom6clhphGIUF9e6YSvKuwuiZ-1lMYFg8C_4",
|
heroImageUrl = "https://lh3.googleusercontent.com/aida-public/AB6AXuD3hBjDpw00tDCQsK5xNcnJra301k1T4LksWVZzHieH9KHQItEQkVzhwevJvf8RkaQKdVKvObzRlfDDqa3_PNwLUlUQc1LpDih8p94VTGobEV62qi7QrmNyQm_o55KRMNWiTG3zLLpblGqo3uUNQcYmPFqfNML95dClXQ4lQNl85-zgerPPAbGPr23dswbIYCigyTAaXgrmdV_nbNQ5LdDB0Wh5cMHtP0uxz6k3ARjNom6clhphGIUF9e6YSvKuwuiZ-1lMYFg8C_4",
|
||||||
audioTrack = "English (Dolby Atmos)",
|
audioTrack = "English (Dolby Atmos)",
|
||||||
subtitles = "English, Spanish, French",
|
subtitles = "English, Spanish, French",
|
||||||
|
progress = 45.0,
|
||||||
cast = castMembers
|
cast = castMembers
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import androidx.compose.foundation.layout.Spacer
|
|||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.sizeIn
|
||||||
import androidx.compose.foundation.layout.statusBarsPadding
|
import androidx.compose.foundation.layout.statusBarsPadding
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
@@ -34,8 +35,8 @@ import hu.bbara.purefin.common.ui.MediaMetaChip
|
|||||||
import hu.bbara.purefin.common.ui.MediaSynopsis
|
import hu.bbara.purefin.common.ui.MediaSynopsis
|
||||||
import hu.bbara.purefin.common.ui.components.GhostIconButton
|
import hu.bbara.purefin.common.ui.components.GhostIconButton
|
||||||
import hu.bbara.purefin.common.ui.components.MediaActionButton
|
import hu.bbara.purefin.common.ui.components.MediaActionButton
|
||||||
import hu.bbara.purefin.common.ui.components.MediaPlayButton
|
|
||||||
import hu.bbara.purefin.common.ui.components.MediaPlaybackSettings
|
import hu.bbara.purefin.common.ui.components.MediaPlaybackSettings
|
||||||
|
import hu.bbara.purefin.common.ui.components.MediaResumeButton
|
||||||
import hu.bbara.purefin.data.model.Episode
|
import hu.bbara.purefin.data.model.Episode
|
||||||
import hu.bbara.purefin.player.PlayerActivity
|
import hu.bbara.purefin.player.PlayerActivity
|
||||||
|
|
||||||
@@ -119,11 +120,20 @@ internal fun EpisodeDetails(
|
|||||||
Spacer(modifier = Modifier.height(24.dp))
|
Spacer(modifier = Modifier.height(24.dp))
|
||||||
|
|
||||||
Row() {
|
Row() {
|
||||||
MediaPlayButton(
|
// MediaPlayButton(
|
||||||
backgroundColor = MaterialTheme.colorScheme.primary,
|
// backgroundColor = MaterialTheme.colorScheme.primary,
|
||||||
foregroundColor = MaterialTheme.colorScheme.onPrimary,
|
// foregroundColor = MaterialTheme.colorScheme.onPrimary,
|
||||||
size = 48.dp,
|
// text = if (episode.progress == null) "Play" else "Resume",
|
||||||
onClick = playAction
|
// subText = if (episode.progress == null) null else "${episode.progress.toInt() }%",
|
||||||
|
// modifier = Modifier.weight(1f),
|
||||||
|
// size = 48.dp,
|
||||||
|
// onClick = playAction
|
||||||
|
// )
|
||||||
|
MediaResumeButton(
|
||||||
|
text = if (episode.progress == null) "Play" else "Resume",
|
||||||
|
progress = episode.progress?.div(100)?.toFloat() ?: 0f,
|
||||||
|
onClick = playAction,
|
||||||
|
modifier = Modifier.sizeIn(maxWidth = 200.dp)
|
||||||
)
|
)
|
||||||
VerticalDivider(
|
VerticalDivider(
|
||||||
color = MaterialTheme.colorScheme.secondary,
|
color = MaterialTheme.colorScheme.secondary,
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import androidx.compose.foundation.layout.Spacer
|
|||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.sizeIn
|
||||||
import androidx.compose.foundation.layout.statusBarsPadding
|
import androidx.compose.foundation.layout.statusBarsPadding
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
@@ -36,8 +37,8 @@ import hu.bbara.purefin.common.ui.MediaMetaChip
|
|||||||
import hu.bbara.purefin.common.ui.MediaSynopsis
|
import hu.bbara.purefin.common.ui.MediaSynopsis
|
||||||
import hu.bbara.purefin.common.ui.components.GhostIconButton
|
import hu.bbara.purefin.common.ui.components.GhostIconButton
|
||||||
import hu.bbara.purefin.common.ui.components.MediaActionButton
|
import hu.bbara.purefin.common.ui.components.MediaActionButton
|
||||||
import hu.bbara.purefin.common.ui.components.MediaPlayButton
|
|
||||||
import hu.bbara.purefin.common.ui.components.MediaPlaybackSettings
|
import hu.bbara.purefin.common.ui.components.MediaPlaybackSettings
|
||||||
|
import hu.bbara.purefin.common.ui.components.MediaResumeButton
|
||||||
import hu.bbara.purefin.download.DownloadState
|
import hu.bbara.purefin.download.DownloadState
|
||||||
import hu.bbara.purefin.player.PlayerActivity
|
import hu.bbara.purefin.player.PlayerActivity
|
||||||
|
|
||||||
@@ -117,11 +118,11 @@ internal fun MovieDetails(
|
|||||||
Spacer(modifier = Modifier.height(24.dp))
|
Spacer(modifier = Modifier.height(24.dp))
|
||||||
|
|
||||||
Row() {
|
Row() {
|
||||||
MediaPlayButton(
|
MediaResumeButton(
|
||||||
backgroundColor = MaterialTheme.colorScheme.primary,
|
text = if (movie.progress == null) "Play" else "Resume",
|
||||||
foregroundColor = MaterialTheme.colorScheme.onPrimary,
|
progress = movie.progress?.div(100)?.toFloat() ?: 0f,
|
||||||
size = 48.dp,
|
onClick = playAction,
|
||||||
onClick = playAction
|
modifier = Modifier.sizeIn(maxWidth = 200.dp)
|
||||||
)
|
)
|
||||||
VerticalDivider(
|
VerticalDivider(
|
||||||
color = MaterialTheme.colorScheme.secondary,
|
color = MaterialTheme.colorScheme.secondary,
|
||||||
|
|||||||
@@ -19,5 +19,6 @@ data class MovieUiModel(
|
|||||||
val heroImageUrl: String,
|
val heroImageUrl: String,
|
||||||
val audioTrack: String,
|
val audioTrack: String,
|
||||||
val subtitles: String,
|
val subtitles: String,
|
||||||
|
val progress: Double?,
|
||||||
val cast: List<CastMember>
|
val cast: List<CastMember>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ class MovieScreenViewModel @Inject constructor(
|
|||||||
heroImageUrl = heroImageUrl,
|
heroImageUrl = heroImageUrl,
|
||||||
audioTrack = audioTrack,
|
audioTrack = audioTrack,
|
||||||
subtitles = subtitles,
|
subtitles = subtitles,
|
||||||
|
progress = progress,
|
||||||
cast = cast.map { CastMember(name = it.name, role = it.role, imageUrl = it.imageUrl) }
|
cast = cast.map { CastMember(name = it.name, role = it.role, imageUrl = it.imageUrl) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package hu.bbara.purefin.common.ui.components
|
|||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
@@ -26,6 +27,8 @@ import androidx.compose.ui.unit.dp
|
|||||||
fun MediaPlayButton(
|
fun MediaPlayButton(
|
||||||
backgroundColor: Color,
|
backgroundColor: Color,
|
||||||
foregroundColor: Color,
|
foregroundColor: Color,
|
||||||
|
text: String = "Play",
|
||||||
|
subText: String? = null,
|
||||||
size: Dp,
|
size: Dp,
|
||||||
onClick: () -> Unit,
|
onClick: () -> Unit,
|
||||||
modifier: Modifier = Modifier
|
modifier: Modifier = Modifier
|
||||||
@@ -46,13 +49,25 @@ fun MediaPlayButton(
|
|||||||
tint = foregroundColor,
|
tint = foregroundColor,
|
||||||
modifier = Modifier.size(42.dp)
|
modifier = Modifier.size(42.dp)
|
||||||
)
|
)
|
||||||
Text(
|
Column() {
|
||||||
text = "Play",
|
Text(
|
||||||
color = foregroundColor,
|
text = text,
|
||||||
fontSize = TextUnit(
|
color = foregroundColor,
|
||||||
value = 16f,
|
fontSize = TextUnit(
|
||||||
type = TextUnitType.Sp
|
value = 16f,
|
||||||
|
type = TextUnitType.Sp
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
subText?.let {
|
||||||
|
Text(
|
||||||
|
text = subText,
|
||||||
|
color = foregroundColor.copy(alpha = 0.7f),
|
||||||
|
fontSize = TextUnit(
|
||||||
|
value = 14f,
|
||||||
|
type = TextUnitType.Sp
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
package hu.bbara.purefin.common.ui.components
|
||||||
|
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.BoxWithConstraints
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.width
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.filled.PlayArrow
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.clip
|
||||||
|
import androidx.compose.ui.draw.drawWithContent
|
||||||
|
import androidx.compose.ui.graphics.drawscope.clipRect
|
||||||
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun MediaResumeButton(
|
||||||
|
text: String,
|
||||||
|
progress: Float = 0f,
|
||||||
|
onClick: () -> Unit,
|
||||||
|
modifier: Modifier = Modifier
|
||||||
|
) {
|
||||||
|
val primaryColor = MaterialTheme.colorScheme.primary
|
||||||
|
val onPrimaryColor = MaterialTheme.colorScheme.onPrimary
|
||||||
|
|
||||||
|
BoxWithConstraints(
|
||||||
|
modifier = modifier
|
||||||
|
.height(52.dp)
|
||||||
|
.clip(RoundedCornerShape(50))
|
||||||
|
.clickable(onClick = onClick)
|
||||||
|
) {
|
||||||
|
// Bottom layer: inverted colors (visible for the remaining %)
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.background(onPrimaryColor),
|
||||||
|
contentAlignment = Alignment.Center
|
||||||
|
) {
|
||||||
|
ButtonContent(text = text, color = primaryColor)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Top layer: primary colors, clipped to the progress %
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.drawWithContent {
|
||||||
|
val clipWidth = size.width * progress
|
||||||
|
clipRect(
|
||||||
|
left = 0f,
|
||||||
|
top = 0f,
|
||||||
|
right = clipWidth,
|
||||||
|
bottom = size.height
|
||||||
|
) {
|
||||||
|
this@drawWithContent.drawContent()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.background(primaryColor),
|
||||||
|
contentAlignment = Alignment.Center
|
||||||
|
) {
|
||||||
|
ButtonContent(text = text, color = onPrimaryColor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun ButtonContent(text: String, color: androidx.compose.ui.graphics.Color) {
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
horizontalArrangement = Arrangement.Center
|
||||||
|
) {
|
||||||
|
Text(text, color = color, fontWeight = FontWeight.Bold, fontSize = 16.sp)
|
||||||
|
Spacer(Modifier.width(8.dp))
|
||||||
|
Icon(Icons.Filled.PlayArrow, null, tint = color)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user