From a33ad982dec56f275f2203e69d46cda7fd0b81b3 Mon Sep 17 00:00:00 2001 From: tapframe <85391825+tapframe@users.noreply.github.com> Date: Sun, 29 Mar 2026 14:10:18 +0530 Subject: [PATCH] feat: Add new SVG icons for player controls and update DetailActionButtons to support saved state --- .../drawable/ic_player_aspect_ratio.svg | 4 ++ .../drawable/ic_player_audio_filled.svg | 6 ++ .../drawable/ic_player_pause.svg | 5 ++ .../drawable/ic_player_play.svg | 4 ++ .../drawable/ic_player_subtitles.svg | 4 ++ .../drawable/library_add_plus.svg | 4 ++ .../drawable/trailer_play_button.svg | 23 ++++++++ .../app/features/details/MetaDetailsScreen.kt | 1 + .../details/components/DetailActionButtons.kt | 37 ++++++++---- .../app/features/player/PlayerControls.kt | 56 +++++++++++++------ 10 files changed, 116 insertions(+), 28 deletions(-) create mode 100644 composeApp/src/commonMain/composeResources/drawable/ic_player_aspect_ratio.svg create mode 100644 composeApp/src/commonMain/composeResources/drawable/ic_player_audio_filled.svg create mode 100644 composeApp/src/commonMain/composeResources/drawable/ic_player_pause.svg create mode 100644 composeApp/src/commonMain/composeResources/drawable/ic_player_play.svg create mode 100644 composeApp/src/commonMain/composeResources/drawable/ic_player_subtitles.svg create mode 100644 composeApp/src/commonMain/composeResources/drawable/library_add_plus.svg create mode 100644 composeApp/src/commonMain/composeResources/drawable/trailer_play_button.svg diff --git a/composeApp/src/commonMain/composeResources/drawable/ic_player_aspect_ratio.svg b/composeApp/src/commonMain/composeResources/drawable/ic_player_aspect_ratio.svg new file mode 100644 index 000000000..a79457c84 --- /dev/null +++ b/composeApp/src/commonMain/composeResources/drawable/ic_player_aspect_ratio.svg @@ -0,0 +1,4 @@ + + + + diff --git a/composeApp/src/commonMain/composeResources/drawable/ic_player_audio_filled.svg b/composeApp/src/commonMain/composeResources/drawable/ic_player_audio_filled.svg new file mode 100644 index 000000000..3c6d8a625 --- /dev/null +++ b/composeApp/src/commonMain/composeResources/drawable/ic_player_audio_filled.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/composeApp/src/commonMain/composeResources/drawable/ic_player_pause.svg b/composeApp/src/commonMain/composeResources/drawable/ic_player_pause.svg new file mode 100644 index 000000000..bc61a66bb --- /dev/null +++ b/composeApp/src/commonMain/composeResources/drawable/ic_player_pause.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/composeApp/src/commonMain/composeResources/drawable/ic_player_play.svg b/composeApp/src/commonMain/composeResources/drawable/ic_player_play.svg new file mode 100644 index 000000000..934941ca7 --- /dev/null +++ b/composeApp/src/commonMain/composeResources/drawable/ic_player_play.svg @@ -0,0 +1,4 @@ + + + + diff --git a/composeApp/src/commonMain/composeResources/drawable/ic_player_subtitles.svg b/composeApp/src/commonMain/composeResources/drawable/ic_player_subtitles.svg new file mode 100644 index 000000000..bd7cdf226 --- /dev/null +++ b/composeApp/src/commonMain/composeResources/drawable/ic_player_subtitles.svg @@ -0,0 +1,4 @@ + + + + diff --git a/composeApp/src/commonMain/composeResources/drawable/library_add_plus.svg b/composeApp/src/commonMain/composeResources/drawable/library_add_plus.svg new file mode 100644 index 000000000..f79533f3d --- /dev/null +++ b/composeApp/src/commonMain/composeResources/drawable/library_add_plus.svg @@ -0,0 +1,4 @@ + + + + diff --git a/composeApp/src/commonMain/composeResources/drawable/trailer_play_button.svg b/composeApp/src/commonMain/composeResources/drawable/trailer_play_button.svg new file mode 100644 index 000000000..84750110c --- /dev/null +++ b/composeApp/src/commonMain/composeResources/drawable/trailer_play_button.svg @@ -0,0 +1,23 @@ + + + + + + + + + + diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/details/MetaDetailsScreen.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/details/MetaDetailsScreen.kt index 26b3f1e77..a7e3c5559 100644 --- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/details/MetaDetailsScreen.kt +++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/details/MetaDetailsScreen.kt @@ -186,6 +186,7 @@ fun MetaDetailsScreen( DetailActionButtons( playLabel = playButtonLabel, saveLabel = if (isSaved) "Saved" else "Save", + isSaved = isSaved, onPlayClick = { when { meta.type == "series" && seriesAction != null -> { diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/details/components/DetailActionButtons.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/details/components/DetailActionButtons.kt index d43a3a431..b5e37cacd 100644 --- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/details/components/DetailActionButtons.kt +++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/details/components/DetailActionButtons.kt @@ -10,8 +10,7 @@ import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.BookmarkBorder -import androidx.compose.material.icons.filled.PlayArrow +import androidx.compose.material.icons.filled.Check import androidx.compose.material3.Button import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Icon @@ -22,15 +21,23 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp +import nuvio.composeapp.generated.resources.Res +import nuvio.composeapp.generated.resources.ic_player_play +import nuvio.composeapp.generated.resources.library_add_plus +import org.jetbrains.compose.resources.painterResource @Composable fun DetailActionButtons( modifier: Modifier = Modifier, playLabel: String = "Play", saveLabel: String = "Save", + isSaved: Boolean = false, onPlayClick: () -> Unit = {}, onSaveClick: () -> Unit = {}, ) { + val playPainter = painterResource(Res.drawable.ic_player_play) + val libraryAddPainter = painterResource(Res.drawable.library_add_plus) + Row( modifier = modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(12.dp), @@ -38,7 +45,6 @@ fun DetailActionButtons( Button( onClick = onPlayClick, modifier = Modifier - .weight(1f) .height(50.dp), shape = RoundedCornerShape(40.dp), @@ -48,9 +54,9 @@ fun DetailActionButtons( ), ) { Icon( - imageVector = Icons.Default.PlayArrow, + painter = playPainter, contentDescription = null, - modifier = Modifier.size(22.dp), + modifier = Modifier.size(18.dp), ) Spacer(modifier = Modifier.width(6.dp)) Text( @@ -69,12 +75,21 @@ fun DetailActionButtons( shape = RoundedCornerShape(40.dp), border = BorderStroke(1.dp, MaterialTheme.colorScheme.outline), ) { - Icon( - imageVector = Icons.Default.BookmarkBorder, - contentDescription = null, - modifier = Modifier.size(20.dp), - tint = MaterialTheme.colorScheme.onSurface, - ) + if (isSaved) { + Icon( + imageVector = Icons.Default.Check, + contentDescription = null, + modifier = Modifier.size(20.dp), + tint = MaterialTheme.colorScheme.onSurface, + ) + } else { + Icon( + painter = libraryAddPainter, + contentDescription = null, + modifier = Modifier.size(18.dp), + tint = MaterialTheme.colorScheme.onSurface, + ) + } Spacer(modifier = Modifier.width(6.dp)) Text( text = saveLabel, diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerControls.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerControls.kt index b14c722da..d48a5a581 100644 --- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerControls.kt +++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerControls.kt @@ -20,14 +20,9 @@ import androidx.compose.foundation.layout.windowInsetsPadding import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.rounded.AspectRatio import androidx.compose.material.icons.rounded.Forward10 -import androidx.compose.material.icons.rounded.Pause -import androidx.compose.material.icons.rounded.PlayArrow import androidx.compose.material.icons.rounded.Replay10 import androidx.compose.material.icons.rounded.Speed -import androidx.compose.material.icons.rounded.Subtitles -import androidx.compose.material.icons.rounded.Audiotrack import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme @@ -41,12 +36,21 @@ import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.painter.Painter +import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import com.nuvio.app.core.ui.NuvioBackButton import com.nuvio.app.core.ui.nuvioTypeScale +import nuvio.composeapp.generated.resources.Res +import nuvio.composeapp.generated.resources.ic_player_aspect_ratio +import nuvio.composeapp.generated.resources.ic_player_audio_filled +import nuvio.composeapp.generated.resources.ic_player_pause +import nuvio.composeapp.generated.resources.ic_player_play +import nuvio.composeapp.generated.resources.ic_player_subtitles +import org.jetbrains.compose.resources.painterResource @Composable internal fun PlayerControlsShell( @@ -318,6 +322,10 @@ private fun PlayPauseControlButton( metrics: PlayerLayoutMetrics, onClick: () -> Unit, ) { + val playPausePainter = painterResource( + if (isPlaying) Res.drawable.ic_player_pause else Res.drawable.ic_player_play, + ) + Box( modifier = Modifier .clip(CircleShape) @@ -334,7 +342,7 @@ private fun PlayPauseControlButton( ) } else { Icon( - imageVector = if (isPlaying) Icons.Rounded.Pause else Icons.Rounded.PlayArrow, + painter = playPausePainter, contentDescription = if (isPlaying) "Pause" else "Play", tint = Color.White, modifier = Modifier.size(metrics.playIconSize), @@ -358,6 +366,10 @@ private fun ProgressControls( modifier: Modifier = Modifier, ) { val durationMs = playbackSnapshot.durationMs.coerceAtLeast(1L) + val aspectRatioPainter = painterResource(Res.drawable.ic_player_aspect_ratio) + val subtitlesPainter = painterResource(Res.drawable.ic_player_subtitles) + val audioPainter = painterResource(Res.drawable.ic_player_audio_filled) + Column(modifier = modifier) { Slider( modifier = Modifier @@ -399,23 +411,23 @@ private fun ProgressControls( verticalAlignment = Alignment.CenterVertically, ) { PlayerActionPillButton( - icon = Icons.Rounded.AspectRatio, label = resizeMode.label, + painter = aspectRatioPainter, onClick = onResizeModeClick, ) PlayerActionPillButton( - icon = Icons.Rounded.Speed, label = "${playbackSnapshot.playbackSpeed}x", + icon = Icons.Rounded.Speed, onClick = onSpeedClick, ) PlayerActionPillButton( - icon = Icons.Rounded.Subtitles, label = "Subs", + painter = subtitlesPainter, onClick = onSubtitleClick, ) PlayerActionPillButton( - icon = Icons.Rounded.Audiotrack, label = "Audio", + painter = audioPainter, onClick = onAudioClick, ) } @@ -450,9 +462,10 @@ private fun TimePill( @Composable private fun PlayerActionPillButton( - icon: androidx.compose.ui.graphics.vector.ImageVector, label: String, onClick: () -> Unit, + icon: ImageVector? = null, + painter: Painter? = null, ) { Row( modifier = Modifier @@ -462,12 +475,21 @@ private fun PlayerActionPillButton( horizontalArrangement = Arrangement.spacedBy(8.dp), verticalAlignment = Alignment.CenterVertically, ) { - Icon( - imageVector = icon, - contentDescription = label, - tint = Color.White, - modifier = Modifier.size(18.dp), - ) + when { + painter != null -> Icon( + painter = painter, + contentDescription = label, + tint = Color.White, + modifier = Modifier.size(18.dp), + ) + + icon != null -> Icon( + imageVector = icon, + contentDescription = label, + tint = Color.White, + modifier = Modifier.size(18.dp), + ) + } Text( text = label, style = MaterialTheme.nuvioTypeScale.labelSm,