feat(stations): обложка текущего трека на карточке станции + подпись
Для станций без своей обложки (и для Radio Record — единый стиль) карточка показывает обложку играющего трека с тёмным градиентом и подписью трек/исполнитель. Источник — /now-playing (теперь с name станции), матч по имени, обновление 20с. Приоритет: трек -> логотип станции -> фирменная плитка.
This commit is contained in:
@@ -25,8 +25,8 @@ import androidx.compose.ui.unit.dp
|
||||
import coil.compose.AsyncImage
|
||||
import com.composables.icons.lucide.Heart
|
||||
import com.composables.icons.lucide.Lucide
|
||||
import com.composables.icons.lucide.Radio
|
||||
import com.radiola.domain.model.Station
|
||||
import com.radiola.domain.model.Track
|
||||
import com.radiola.ui.theme.Motion
|
||||
import com.radiola.ui.theme.RadiolaTheme
|
||||
import com.radiola.ui.theme.pressScale
|
||||
@@ -37,7 +37,8 @@ fun StationCard(
|
||||
isFavorite: Boolean,
|
||||
onClick: () -> Unit,
|
||||
onFavoriteClick: () -> Unit,
|
||||
modifier: Modifier = Modifier
|
||||
modifier: Modifier = Modifier,
|
||||
nowTrack: Track? = null
|
||||
) {
|
||||
val colors = RadiolaTheme.colors
|
||||
val haptics = LocalHapticFeedback.current
|
||||
@@ -60,37 +61,84 @@ fun StationCard(
|
||||
.clip(RoundedCornerShape(16.dp))
|
||||
.background(colors.surface2)
|
||||
) {
|
||||
if (!station.coverUrl.isNullOrBlank()) {
|
||||
AsyncImage(
|
||||
model = crossfadeModel(station.coverUrl),
|
||||
contentDescription = station.name,
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
contentScale = ContentScale.Crop
|
||||
)
|
||||
} else {
|
||||
// Своя фирменная плитка станции (цвет из названия + инициалы),
|
||||
// а не общий значок и не чужая обложка.
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.background(stationTileBrush(station.name)),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Text(
|
||||
text = stationInitials(station.name),
|
||||
color = androidx.compose.ui.graphics.Color.White,
|
||||
fontWeight = FontWeight.Black,
|
||||
style = androidx.compose.material3.MaterialTheme.typography.headlineMedium
|
||||
when {
|
||||
// Приоритет 1: обложка текущего трека с градиентом и подписью.
|
||||
!nowTrack?.coverUrl.isNullOrBlank() -> {
|
||||
AsyncImage(
|
||||
model = crossfadeModel(nowTrack!!.coverUrl),
|
||||
contentDescription = nowTrack.song,
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
contentScale = ContentScale.Crop
|
||||
)
|
||||
// Тёмный скрим снизу для читаемости текста.
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.background(
|
||||
Brush.verticalGradient(
|
||||
0f to Color.Transparent,
|
||||
0.5f to Color.Transparent,
|
||||
1f to Color.Black.copy(alpha = 0.8f)
|
||||
)
|
||||
)
|
||||
)
|
||||
// Название трека и исполнитель в нижнем-левом углу.
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.align(Alignment.BottomStart)
|
||||
.padding(10.dp)
|
||||
) {
|
||||
Text(
|
||||
text = nowTrack.song,
|
||||
color = Color.White,
|
||||
fontWeight = FontWeight.Bold,
|
||||
style = androidx.compose.material3.MaterialTheme.typography.bodyMedium,
|
||||
maxLines = 1,
|
||||
overflow = androidx.compose.ui.text.style.TextOverflow.Ellipsis
|
||||
)
|
||||
Text(
|
||||
text = nowTrack.artist,
|
||||
color = Color.White.copy(alpha = 0.8f),
|
||||
style = androidx.compose.material3.MaterialTheme.typography.labelMedium,
|
||||
maxLines = 1,
|
||||
overflow = androidx.compose.ui.text.style.TextOverflow.Ellipsis
|
||||
)
|
||||
}
|
||||
}
|
||||
// Приоритет 2: логотип самой станции.
|
||||
!station.coverUrl.isNullOrBlank() -> {
|
||||
AsyncImage(
|
||||
model = crossfadeModel(station.coverUrl),
|
||||
contentDescription = station.name,
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
contentScale = ContentScale.Crop
|
||||
)
|
||||
}
|
||||
// Приоритет 3: фирменная плитка (цвет из названия + инициалы).
|
||||
else -> {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.background(stationTileBrush(station.name)),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Text(
|
||||
text = stationInitials(station.name),
|
||||
color = Color.White,
|
||||
fontWeight = FontWeight.Black,
|
||||
style = androidx.compose.material3.MaterialTheme.typography.headlineMedium
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
// Кнопка сердечка — поверх всего, top-end.
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.align(Alignment.TopEnd)
|
||||
.padding(10.dp)
|
||||
.size(32.dp)
|
||||
.clip(RoundedCornerShape(16.dp))
|
||||
.background(androidx.compose.ui.graphics.Color.Black.copy(alpha = 0.4f))
|
||||
.background(Color.Black.copy(alpha = 0.4f))
|
||||
.clickable {
|
||||
haptics.performHapticFeedback(HapticFeedbackType.LongPress)
|
||||
onFavoriteClick()
|
||||
|
||||
Reference in New Issue
Block a user