mirror of
https://github.com/bbara04/Purefin.git
synced 2026-03-31 17:10:08 +02:00
feat: implement track selection buttons for quality, audio, and subtitles
This commit is contained in:
@@ -44,7 +44,6 @@ 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.viewmodel.PlayerViewModel
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.roundToInt
|
||||
@@ -65,13 +64,11 @@ fun PlayerScreen(
|
||||
val maxVolume = remember { audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC).coerceAtLeast(1) }
|
||||
var volume by remember { mutableStateOf(audioManager.getStreamVolume(AudioManager.STREAM_MUSIC) / maxVolume.toFloat()) }
|
||||
var brightness by remember { mutableStateOf(readCurrentBrightness(activity)) }
|
||||
var showSettings by remember { mutableStateOf(false) }
|
||||
var showQueuePanel by remember { mutableStateOf(false) }
|
||||
var horizontalSeekFeedback by remember { mutableStateOf<Long?>(null) }
|
||||
|
||||
LaunchedEffect(uiState.isPlaying) {
|
||||
if (uiState.isPlaying) {
|
||||
showSettings = false
|
||||
showQueuePanel = false
|
||||
}
|
||||
}
|
||||
@@ -185,15 +182,7 @@ fun PlayerScreen(
|
||||
onSeekLiveEdge = { viewModel.seekToLiveEdge() },
|
||||
onNext = { viewModel.next() },
|
||||
onPrevious = { viewModel.previous() },
|
||||
onToggleCaptions = {
|
||||
val off = uiState.textTracks.firstOrNull { it.isOff }
|
||||
val currentId = uiState.selectedTextTrackId
|
||||
val next = if (currentId == off?.id) {
|
||||
uiState.textTracks.firstOrNull { !it.isOff }
|
||||
} else off
|
||||
next?.let { viewModel.selectTrack(it) }
|
||||
},
|
||||
onShowSettings = { showSettings = true },
|
||||
onSelectTrack = { viewModel.selectTrack(it) },
|
||||
onQueueSelected = { viewModel.playQueueItem(it) },
|
||||
onOpenQueue = { showQueuePanel = true }
|
||||
)
|
||||
@@ -210,14 +199,6 @@ fun PlayerScreen(
|
||||
onDismissError = { viewModel.clearError() }
|
||||
)
|
||||
|
||||
PlayerSettingsSheet(
|
||||
visible = showSettings,
|
||||
uiState = uiState,
|
||||
onDismiss = { showSettings = false },
|
||||
onSelectTrack = { viewModel.selectTrack(it) },
|
||||
onSpeedSelected = { viewModel.setPlaybackSpeed(it) }
|
||||
)
|
||||
|
||||
AnimatedVisibility(
|
||||
visible = showQueuePanel,
|
||||
enter = slideInHorizontally { it },
|
||||
|
||||
@@ -20,10 +20,8 @@ import androidx.compose.material.icons.outlined.Pause
|
||||
import androidx.compose.material.icons.outlined.PlayArrow
|
||||
import androidx.compose.material.icons.outlined.PlaylistPlay
|
||||
import androidx.compose.material.icons.outlined.Replay10
|
||||
import androidx.compose.material.icons.outlined.Settings
|
||||
import androidx.compose.material.icons.outlined.SkipNext
|
||||
import androidx.compose.material.icons.outlined.SkipPrevious
|
||||
import androidx.compose.material.icons.outlined.Subtitles
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
@@ -40,6 +38,7 @@ import androidx.compose.ui.unit.dp
|
||||
import hu.bbara.purefin.common.ui.components.GhostIconButton
|
||||
import hu.bbara.purefin.common.ui.components.PurefinIconButton
|
||||
import hu.bbara.purefin.player.model.PlayerUiState
|
||||
import hu.bbara.purefin.player.model.TrackOption
|
||||
|
||||
@Composable
|
||||
fun PlayerControlsOverlay(
|
||||
@@ -52,8 +51,7 @@ fun PlayerControlsOverlay(
|
||||
onSeekLiveEdge: () -> Unit,
|
||||
onNext: () -> Unit,
|
||||
onPrevious: () -> Unit,
|
||||
onToggleCaptions: () -> Unit,
|
||||
onShowSettings: () -> Unit,
|
||||
onSelectTrack: (TrackOption) -> Unit,
|
||||
onQueueSelected: (String) -> Unit,
|
||||
onOpenQueue: () -> Unit,
|
||||
modifier: Modifier = Modifier
|
||||
@@ -100,8 +98,7 @@ fun PlayerControlsOverlay(
|
||||
onSeekForward = { onSeekRelative(30_000) },
|
||||
onSeekBackward = { onSeekRelative(-10_000) },
|
||||
onSeekLiveEdge = onSeekLiveEdge,
|
||||
onToggleCaptions = onToggleCaptions,
|
||||
onShowSettings = onShowSettings,
|
||||
onSelectTrack = onSelectTrack,
|
||||
onQueueSelected = onQueueSelected,
|
||||
modifier = Modifier.align(Alignment.BottomCenter)
|
||||
)
|
||||
@@ -163,8 +160,7 @@ private fun BottomSection(
|
||||
onSeekForward: () -> Unit,
|
||||
onSeekBackward: () -> Unit,
|
||||
onSeekLiveEdge: () -> Unit,
|
||||
onToggleCaptions: () -> Unit,
|
||||
onShowSettings: () -> Unit,
|
||||
onSelectTrack: (TrackOption) -> Unit,
|
||||
onQueueSelected: (String) -> Unit,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
@@ -259,15 +255,20 @@ private fun BottomSection(
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
PurefinIconButton(
|
||||
icon = Icons.Outlined.Subtitles,
|
||||
contentDescription = "Captions",
|
||||
onClick = onToggleCaptions
|
||||
QualitySelectionButton(
|
||||
options = uiState.qualityTracks,
|
||||
selectedId = uiState.selectedQualityTrackId,
|
||||
onSelect = onSelectTrack
|
||||
)
|
||||
PurefinIconButton(
|
||||
icon = Icons.Outlined.Settings,
|
||||
contentDescription = "Settings",
|
||||
onClick = onShowSettings
|
||||
AudioSelectionButton(
|
||||
options = uiState.audioTracks,
|
||||
selectedId = uiState.selectedAudioTrackId,
|
||||
onSelect = onSelectTrack
|
||||
)
|
||||
SubtitlesSelectionButton(
|
||||
options = uiState.textTracks,
|
||||
selectedId = uiState.selectedTextTrackId,
|
||||
onSelect = onSelectTrack
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,196 +0,0 @@
|
||||
package hu.bbara.purefin.player.ui.components
|
||||
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.slideInVertically
|
||||
import androidx.compose.animation.slideOutVertically
|
||||
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.Column
|
||||
import androidx.compose.foundation.layout.ExperimentalLayoutApi
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.outlined.Close
|
||||
import androidx.compose.material.icons.outlined.ClosedCaption
|
||||
import androidx.compose.material.icons.outlined.HighQuality
|
||||
import androidx.compose.material.icons.outlined.Language
|
||||
import androidx.compose.material.icons.outlined.Speed
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
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.unit.dp
|
||||
import hu.bbara.purefin.player.model.PlayerUiState
|
||||
import hu.bbara.purefin.player.model.TrackOption
|
||||
|
||||
@Composable
|
||||
fun PlayerSettingsSheet(
|
||||
visible: Boolean,
|
||||
uiState: PlayerUiState,
|
||||
onDismiss: () -> Unit,
|
||||
onSelectTrack: (TrackOption) -> Unit,
|
||||
onSpeedSelected: (Float) -> Unit
|
||||
) {
|
||||
val scheme = MaterialTheme.colorScheme
|
||||
AnimatedVisibility(
|
||||
visible = visible,
|
||||
enter = slideInVertically(initialOffsetY = { it }) + androidx.compose.animation.fadeIn(),
|
||||
exit = slideOutVertically(targetOffsetY = { it }) + androidx.compose.animation.fadeOut()
|
||||
) {
|
||||
Box(modifier = Modifier.fillMaxWidth(), contentAlignment = Alignment.BottomCenter) {
|
||||
Surface(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clip(RoundedCornerShape(topStart = 24.dp, topEnd = 24.dp)),
|
||||
color = scheme.surface.copy(alpha = 0.98f)
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.verticalScroll(rememberScrollState())
|
||||
.padding(horizontal = 20.dp, vertical = 16.dp)
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Text(text = "Playback settings", color = scheme.onSurface, style = MaterialTheme.typography.titleMedium)
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.Close,
|
||||
contentDescription = "Close",
|
||||
tint = scheme.onSurface,
|
||||
modifier = Modifier
|
||||
.clip(RoundedCornerShape(50))
|
||||
.clickable { onDismiss() }
|
||||
.padding(8.dp)
|
||||
)
|
||||
}
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
TrackGroup(
|
||||
label = "Audio track",
|
||||
icon = { Icon(Icons.Outlined.Language, contentDescription = null, tint = scheme.onSurface) },
|
||||
options = uiState.audioTracks,
|
||||
selectedId = uiState.selectedAudioTrackId,
|
||||
onSelect = onSelectTrack
|
||||
)
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
TrackGroup(
|
||||
label = "Subtitles",
|
||||
icon = { Icon(Icons.Outlined.ClosedCaption, contentDescription = null, tint = scheme.onSurface) },
|
||||
options = uiState.textTracks,
|
||||
selectedId = uiState.selectedTextTrackId,
|
||||
onSelect = onSelectTrack
|
||||
)
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
TrackGroup(
|
||||
label = "Quality",
|
||||
icon = { Icon(Icons.Outlined.HighQuality, contentDescription = null, tint = scheme.onSurface) },
|
||||
options = uiState.qualityTracks,
|
||||
selectedId = uiState.selectedQualityTrackId,
|
||||
onSelect = onSelectTrack
|
||||
)
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
SpeedGroup(
|
||||
selectedSpeed = uiState.playbackSpeed,
|
||||
onSpeedSelected = onSpeedSelected
|
||||
)
|
||||
Spacer(modifier = Modifier.height(4.dp))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun TrackGroup(
|
||||
label: String,
|
||||
icon: @Composable () -> Unit,
|
||||
options: List<TrackOption>,
|
||||
selectedId: String?,
|
||||
onSelect: (TrackOption) -> Unit
|
||||
) {
|
||||
val scheme = MaterialTheme.colorScheme
|
||||
Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
Row(verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
icon()
|
||||
Text(text = label, color = scheme.onSurface, style = MaterialTheme.typography.titleSmall)
|
||||
}
|
||||
FlowChips(
|
||||
items = options,
|
||||
selectedId = selectedId,
|
||||
onSelect = onSelect
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@OptIn(ExperimentalLayoutApi::class)
|
||||
private fun FlowChips(
|
||||
items: List<TrackOption>,
|
||||
selectedId: String?,
|
||||
onSelect: (TrackOption) -> Unit
|
||||
) {
|
||||
val scheme = MaterialTheme.colorScheme
|
||||
androidx.compose.foundation.layout.FlowRow(
|
||||
horizontalArrangement = Arrangement.spacedBy(10.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp)
|
||||
) {
|
||||
items.forEach { option ->
|
||||
val selected = option.id == selectedId
|
||||
Text(
|
||||
text = option.label,
|
||||
color = if (selected) scheme.onPrimary else scheme.onSurface,
|
||||
modifier = Modifier
|
||||
.clip(RoundedCornerShape(12.dp))
|
||||
.background(if (selected) scheme.primary else scheme.surfaceVariant)
|
||||
.clickable { onSelect(option) }
|
||||
.padding(horizontal = 12.dp, vertical = 8.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@OptIn(ExperimentalLayoutApi::class)
|
||||
private fun SpeedGroup(
|
||||
selectedSpeed: Float,
|
||||
onSpeedSelected: (Float) -> Unit
|
||||
) {
|
||||
val options = listOf(0.75f, 1f, 1.25f, 1.5f, 1.75f, 2f)
|
||||
val scheme = MaterialTheme.colorScheme
|
||||
Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
Row(verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
Icon(Icons.Outlined.Speed, contentDescription = null, tint = scheme.onSurface)
|
||||
Text(text = "Playback speed", color = scheme.onSurface, style = MaterialTheme.typography.titleSmall)
|
||||
}
|
||||
androidx.compose.foundation.layout.FlowRow(
|
||||
horizontalArrangement = Arrangement.spacedBy(10.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp)
|
||||
) {
|
||||
options.forEach { speed ->
|
||||
val selected = speed == selectedSpeed
|
||||
Text(
|
||||
text = "${speed}x",
|
||||
color = if (selected) scheme.onPrimary else scheme.onSurface,
|
||||
modifier = Modifier
|
||||
.clip(RoundedCornerShape(12.dp))
|
||||
.background(if (selected) scheme.primary else scheme.surfaceVariant)
|
||||
.clickable { onSpeedSelected(speed) }
|
||||
.padding(horizontal = 12.dp, vertical = 8.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,220 @@
|
||||
package hu.bbara.purefin.player.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.Column
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.heightIn
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.widthIn
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.outlined.ClosedCaption
|
||||
import androidx.compose.material.icons.outlined.HighQuality
|
||||
import androidx.compose.material.icons.outlined.Language
|
||||
import androidx.compose.material3.DropdownMenu
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
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 androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import hu.bbara.purefin.common.ui.components.PurefinIconButton
|
||||
import hu.bbara.purefin.player.model.TrackOption
|
||||
|
||||
@Composable
|
||||
fun QualitySelectionButton(
|
||||
options: List<TrackOption>,
|
||||
selectedId: String?,
|
||||
onSelect: (TrackOption) -> Unit,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
var expanded by remember { mutableStateOf(false) }
|
||||
val scheme = MaterialTheme.colorScheme
|
||||
|
||||
Box(modifier = modifier) {
|
||||
PurefinIconButton(
|
||||
icon = Icons.Outlined.HighQuality,
|
||||
contentDescription = "Quality",
|
||||
onClick = { expanded = true }
|
||||
)
|
||||
|
||||
DropdownMenu(
|
||||
expanded = expanded,
|
||||
onDismissRequest = { expanded = false },
|
||||
modifier = Modifier
|
||||
.widthIn(min = 160.dp, max = 280.dp)
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.background(scheme.surface.copy(alpha = 0.98f))
|
||||
.widthIn(min = 160.dp, max = 280.dp)
|
||||
.heightIn(max = 280.dp)
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.verticalScroll(rememberScrollState())
|
||||
.padding(vertical = 8.dp, horizontal = 8.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(4.dp)
|
||||
) {
|
||||
options.forEach { option ->
|
||||
val selected = option.id == selectedId
|
||||
TrackOptionItem(
|
||||
label = option.label,
|
||||
selected = selected,
|
||||
onClick = {
|
||||
onSelect(option)
|
||||
expanded = false
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun AudioSelectionButton(
|
||||
options: List<TrackOption>,
|
||||
selectedId: String?,
|
||||
onSelect: (TrackOption) -> Unit,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
var expanded by remember { mutableStateOf(false) }
|
||||
val scheme = MaterialTheme.colorScheme
|
||||
|
||||
Box(modifier = modifier) {
|
||||
PurefinIconButton(
|
||||
icon = Icons.Outlined.Language,
|
||||
contentDescription = "Audio",
|
||||
onClick = { expanded = true }
|
||||
)
|
||||
|
||||
DropdownMenu(
|
||||
expanded = expanded,
|
||||
onDismissRequest = { expanded = false },
|
||||
modifier = Modifier
|
||||
.widthIn(min = 160.dp, max = 280.dp)
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.background(scheme.surface.copy(alpha = 0.98f))
|
||||
.widthIn(min = 160.dp, max = 280.dp)
|
||||
.heightIn(max = 280.dp)
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.verticalScroll(rememberScrollState())
|
||||
.padding(vertical = 8.dp, horizontal = 8.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(4.dp)
|
||||
) {
|
||||
options.forEach { option ->
|
||||
val selected = option.id == selectedId
|
||||
TrackOptionItem(
|
||||
label = option.label,
|
||||
selected = selected,
|
||||
onClick = {
|
||||
onSelect(option)
|
||||
expanded = false
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun SubtitlesSelectionButton(
|
||||
options: List<TrackOption>,
|
||||
selectedId: String?,
|
||||
onSelect: (TrackOption) -> Unit,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
var expanded by remember { mutableStateOf(false) }
|
||||
val scheme = MaterialTheme.colorScheme
|
||||
|
||||
Box(modifier = modifier) {
|
||||
PurefinIconButton(
|
||||
icon = Icons.Outlined.ClosedCaption,
|
||||
contentDescription = "Subtitles",
|
||||
onClick = { expanded = true }
|
||||
)
|
||||
|
||||
DropdownMenu(
|
||||
expanded = expanded,
|
||||
onDismissRequest = { expanded = false },
|
||||
modifier = Modifier
|
||||
.widthIn(min = 160.dp, max = 280.dp)
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.background(scheme.surface.copy(alpha = 0.98f))
|
||||
.widthIn(min = 160.dp, max = 280.dp)
|
||||
.heightIn(max = 280.dp)
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.verticalScroll(rememberScrollState())
|
||||
.padding(vertical = 8.dp, horizontal = 8.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(4.dp)
|
||||
) {
|
||||
options.forEach { option ->
|
||||
val selected = option.id == selectedId
|
||||
TrackOptionItem(
|
||||
label = option.label,
|
||||
selected = selected,
|
||||
onClick = {
|
||||
onSelect(option)
|
||||
expanded = false
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun TrackOptionItem(
|
||||
label: String,
|
||||
selected: Boolean,
|
||||
onClick: () -> Unit,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
val scheme = MaterialTheme.colorScheme
|
||||
|
||||
Box(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.clip(RoundedCornerShape(10.dp))
|
||||
.background(
|
||||
if (selected) {
|
||||
scheme.primary.copy(alpha = 0.15f)
|
||||
} else {
|
||||
scheme.surfaceVariant.copy(alpha = 0.6f)
|
||||
}
|
||||
)
|
||||
.clickable(onClick = onClick)
|
||||
.padding(horizontal = 16.dp, vertical = 12.dp)
|
||||
) {
|
||||
Text(
|
||||
text = label,
|
||||
color = scheme.onSurface,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
fontWeight = if (selected) FontWeight.SemiBold else FontWeight.Normal
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user