diff --git a/app/src/main/java/hu/bbara/purefin/common/ui/components/TimedVisibility.kt b/app/src/main/java/hu/bbara/purefin/common/ui/components/TimedVisibility.kt index e06f162..89fbb71 100644 --- a/app/src/main/java/hu/bbara/purefin/common/ui/components/TimedVisibility.kt +++ b/app/src/main/java/hu/bbara/purefin/common/ui/components/TimedVisibility.kt @@ -9,6 +9,7 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier import kotlinx.coroutines.delay /** @@ -25,7 +26,8 @@ import kotlinx.coroutines.delay fun EmptyValueTimedVisibility( value: T?, hideAfterMillis: Long = 1_000, - content: @Composable (T) -> Unit, + modifier: Modifier = Modifier, + content: @Composable (T) -> Unit ) { val shownValue = remember { mutableStateOf(null) } @@ -55,7 +57,8 @@ fun EmptyValueTimedVisibility( fun ValueChangeTimedVisibility( value: T, hideAfterMillis: Long = 1_000, - content: @Composable (T) -> Unit, + modifier: Modifier = Modifier, + content: @Composable (T) -> Unit ) { var displayedValue by remember { mutableStateOf(value) } var isVisible by remember { mutableStateOf(false) } @@ -75,6 +78,7 @@ fun ValueChangeTimedVisibility( AnimatedVisibility( visible = isVisible, + modifier = modifier, enter = EnterTransition.None, exit = ExitTransition.None ) { diff --git a/app/src/main/java/hu/bbara/purefin/player/ui/PlayerScreen.kt b/app/src/main/java/hu/bbara/purefin/player/ui/PlayerScreen.kt index dc3c6fd..4555e61 100644 --- a/app/src/main/java/hu/bbara/purefin/player/ui/PlayerScreen.kt +++ b/app/src/main/java/hu/bbara/purefin/player/ui/PlayerScreen.kt @@ -15,6 +15,9 @@ import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.outlined.BrightnessMedium +import androidx.compose.material.icons.outlined.VolumeUp import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -27,6 +30,7 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.unit.dp import androidx.compose.ui.viewinterop.AndroidView @@ -35,12 +39,12 @@ import androidx.media3.ui.AspectRatioFrameLayout import androidx.media3.ui.PlayerView import hu.bbara.purefin.common.ui.components.EmptyValueTimedVisibility import hu.bbara.purefin.common.ui.components.ValueChangeTimedVisibility +import hu.bbara.purefin.player.ui.components.PlayerAdjustmentIndicator import hu.bbara.purefin.player.ui.components.PlayerControlsOverlay import hu.bbara.purefin.player.ui.components.PlayerGesturesLayer import hu.bbara.purefin.player.ui.components.PlayerLoadingErrorEndCard import hu.bbara.purefin.player.ui.components.PlayerQueuePanel import hu.bbara.purefin.player.ui.components.PlayerSettingsSheet -import hu.bbara.purefin.player.ui.components.PlayerSideSliders import hu.bbara.purefin.player.viewmodel.PlayerViewModel import kotlin.math.abs import kotlin.math.roundToInt @@ -135,27 +139,33 @@ fun PlayerScreen( ValueChangeTimedVisibility( value = brightness, - hideAfterMillis = 800 + hideAfterMillis = 800, + modifier = Modifier + .align(Alignment.CenterStart) + .padding(start = 20.dp) ) { currentBrightness -> - PlayerSideSliders( - modifier = Modifier.fillMaxSize(), - brightness = currentBrightness, - volume = volume, - showBrightness = true, - showVolume = false, + PlayerAdjustmentIndicator( + modifier = Modifier + .align(Alignment.Center), + icon = Icons.Outlined.BrightnessMedium, + contentDescription = "Brightness", + value = currentBrightness ) } ValueChangeTimedVisibility( value = volume, - hideAfterMillis = 800 + hideAfterMillis = 800, + modifier = Modifier + .align(Alignment.CenterEnd) + .padding(end = 20.dp) ) { currentVolume -> - PlayerSideSliders( - modifier = Modifier.fillMaxSize(), - brightness = brightness, - volume = currentVolume, - showBrightness = false, - showVolume = true, + PlayerAdjustmentIndicator( + modifier = Modifier + .align(Alignment.Center), + icon = Icons.Outlined.VolumeUp, + contentDescription = "Volume", + value = currentVolume ) } @@ -235,7 +245,7 @@ private fun SeekAmountIndicator(deltaMs: Long, modifier: Modifier = Modifier) { Box( modifier = modifier .clip(RoundedCornerShape(16.dp)) - .background(scheme.surface.copy(alpha = 0.9f)) + .background(Color.Black.copy(alpha = 0.9f)) .padding(horizontal = 20.dp, vertical = 12.dp) ) { Text( diff --git a/app/src/main/java/hu/bbara/purefin/player/ui/components/PlayerAdjustmentIndicator.kt b/app/src/main/java/hu/bbara/purefin/player/ui/components/PlayerAdjustmentIndicator.kt new file mode 100644 index 0000000..f7444c9 --- /dev/null +++ b/app/src/main/java/hu/bbara/purefin/player/ui/components/PlayerAdjustmentIndicator.kt @@ -0,0 +1,76 @@ +package hu.bbara.purefin.player.ui.components + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.RoundedCornerShape +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.graphics.Color +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import kotlin.math.roundToInt + +@Composable +fun PlayerAdjustmentIndicator( + modifier: Modifier = Modifier, + icon: ImageVector, + contentDescription: String?, + value: Float, + sliderHeight: Dp = 140.dp, +) { + val scheme = MaterialTheme.colorScheme + val percent = (value.coerceIn(0f, 1f) * 100).roundToInt() + val clamped = value.coerceIn(0f, 1f) + + Box( + modifier = modifier + .clip(RoundedCornerShape(16.dp)) + .background(Color.Black.copy(alpha = 0.5f)) + .padding(horizontal = 20.dp, vertical = 16.dp), + contentAlignment = Alignment.Center + ) { + Column( + horizontalAlignment = Alignment.CenterHorizontally + ) { + Icon( + imageVector = icon, + contentDescription = contentDescription, + tint = scheme.onSurface + ) + Spacer(modifier = Modifier.height(16.dp)) + Box( + modifier = Modifier + .width(10.dp) + .height(sliderHeight) + .clip(RoundedCornerShape(5.dp)) + .background(scheme.onSurface.copy(alpha = 0.2f)) + ) { + Box( + modifier = Modifier + .align(Alignment.BottomCenter) + .width(10.dp) + .height(sliderHeight * clamped) + .clip(RoundedCornerShape(5.dp)) + .background(scheme.primary) + ) + } + Spacer(modifier = Modifier.height(16.dp)) + Text( + text = "$percent%", + color = scheme.onSurface, + style = MaterialTheme.typography.titleMedium + ) + } + } +} diff --git a/app/src/main/java/hu/bbara/purefin/player/ui/components/PlayerSideSliders.kt b/app/src/main/java/hu/bbara/purefin/player/ui/components/PlayerSideSliders.kt deleted file mode 100644 index cbeaeb7..0000000 --- a/app/src/main/java/hu/bbara/purefin/player/ui/components/PlayerSideSliders.kt +++ /dev/null @@ -1,84 +0,0 @@ -package hu.bbara.purefin.player.ui.components - -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxHeight -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.wrapContentHeight -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.outlined.BrightnessMedium -import androidx.compose.material.icons.outlined.VolumeUp -import androidx.compose.material3.Icon -import androidx.compose.material3.LinearProgressIndicator -import androidx.compose.material3.MaterialTheme -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.unit.dp - -@Composable -fun PlayerSideSliders( - modifier: Modifier = Modifier, - brightness: Float, - volume: Float, - showBrightness: Boolean, - showVolume: Boolean, -) { - val scheme = MaterialTheme.colorScheme - - Box(modifier = modifier.fillMaxWidth()) { - if (showBrightness) { - SideOverlay( - modifier = Modifier - .align(Alignment.CenterStart) - .padding(start = 16.dp), - icon = { Icon(Icons.Outlined.BrightnessMedium, contentDescription = null, tint = scheme.onBackground) }, - progress = brightness, - scheme = scheme - ) - } - if (showVolume) { - SideOverlay( - modifier = Modifier - .align(Alignment.CenterEnd) - .padding(end = 16.dp), - icon = { Icon(Icons.Outlined.VolumeUp, contentDescription = null, tint = scheme.onBackground) }, - progress = volume, - scheme = scheme - ) - } - } -} - -@Composable -private fun SideOverlay( - modifier: Modifier = Modifier, - icon: @Composable () -> Unit, - progress: Float, - scheme: androidx.compose.material3.ColorScheme -) { - Column( - modifier = modifier - .fillMaxHeight(0.3f) - .wrapContentHeight(align = Alignment.CenterVertically) - .clip(RoundedCornerShape(18.dp)) - .background(scheme.background.copy(alpha = 0.8f)) - .padding(horizontal = 14.dp, vertical = 12.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - icon() - LinearProgressIndicator( - progress = { progress.coerceIn(0f, 1f) }, - modifier = Modifier - .padding(top = 10.dp) - .fillMaxWidth() - .clip(RoundedCornerShape(8.dp)), - color = scheme.primary, - trackColor = scheme.onBackground.copy(alpha = 0.2f) - ) - } -}