bodyLarge.lineHeight не задан (Unspecified), умножение на 1.4f бросало IllegalArgumentException (Cannot perform operation for Unspecified type). Задан конкретный lineHeight = 22.sp.
127 lines
4.1 KiB
Kotlin
127 lines
4.1 KiB
Kotlin
package com.radiola.ui.lyrics
|
||
|
||
import androidx.compose.foundation.layout.*
|
||
import androidx.compose.foundation.rememberScrollState
|
||
import androidx.compose.foundation.verticalScroll
|
||
import androidx.compose.material3.*
|
||
import androidx.compose.runtime.*
|
||
import androidx.compose.ui.Alignment
|
||
import androidx.compose.ui.Modifier
|
||
import androidx.compose.ui.unit.dp
|
||
import androidx.compose.ui.unit.sp
|
||
import androidx.hilt.navigation.compose.hiltViewModel
|
||
import com.radiola.ui.theme.RadiolaTheme
|
||
|
||
/**
|
||
* Содержимое шторки текста песни. Данные загружаются через LyricsViewModel → LRCLIB API.
|
||
* Встраивается в ModalBottomSheet на стороне вызывающего экрана.
|
||
*/
|
||
@Composable
|
||
fun LyricsSheet(
|
||
artist: String,
|
||
song: String,
|
||
durationSec: Int? = null,
|
||
viewModel: LyricsViewModel = hiltViewModel()
|
||
) {
|
||
val colors = RadiolaTheme.colors
|
||
val state by viewModel.state.collectAsState()
|
||
|
||
LaunchedEffect(artist, song) {
|
||
viewModel.load(artist, song, durationSec)
|
||
}
|
||
|
||
Column(
|
||
modifier = Modifier
|
||
.fillMaxWidth()
|
||
.padding(horizontal = 20.dp)
|
||
) {
|
||
// Заголовок
|
||
Text(
|
||
text = song,
|
||
style = MaterialTheme.typography.titleLarge,
|
||
color = colors.textPrimary,
|
||
maxLines = 2
|
||
)
|
||
Spacer(Modifier.height(4.dp))
|
||
Text(
|
||
text = artist,
|
||
style = MaterialTheme.typography.bodyMedium,
|
||
color = colors.textSecondary,
|
||
maxLines = 1
|
||
)
|
||
Spacer(Modifier.height(20.dp))
|
||
|
||
// Состояния
|
||
when (val s = state) {
|
||
is LyricsState.Loading -> {
|
||
Box(
|
||
modifier = Modifier
|
||
.fillMaxWidth()
|
||
.height(180.dp),
|
||
contentAlignment = Alignment.Center
|
||
) {
|
||
CircularProgressIndicator(color = colors.accent)
|
||
}
|
||
}
|
||
|
||
is LyricsState.Instrumental -> {
|
||
Text(
|
||
text = "Инструментальная композиция",
|
||
style = MaterialTheme.typography.bodyLarge,
|
||
color = colors.textMuted,
|
||
modifier = Modifier.padding(vertical = 40.dp)
|
||
)
|
||
}
|
||
|
||
is LyricsState.Found -> {
|
||
Column(
|
||
modifier = Modifier
|
||
.fillMaxWidth()
|
||
.heightIn(max = 480.dp)
|
||
.verticalScroll(rememberScrollState()),
|
||
verticalArrangement = Arrangement.spacedBy(4.dp)
|
||
) {
|
||
s.plain.lines().forEach { line ->
|
||
Text(
|
||
text = line.ifEmpty { " " },
|
||
style = MaterialTheme.typography.bodyLarge,
|
||
color = colors.textPrimary,
|
||
lineHeight = 22.sp
|
||
)
|
||
}
|
||
}
|
||
}
|
||
|
||
is LyricsState.NotFound -> {
|
||
Text(
|
||
text = "Текст не найден",
|
||
style = MaterialTheme.typography.bodyLarge,
|
||
color = colors.textMuted,
|
||
modifier = Modifier.padding(vertical = 40.dp)
|
||
)
|
||
}
|
||
|
||
is LyricsState.Error -> {
|
||
Text(
|
||
text = "Не удалось загрузить текст",
|
||
style = MaterialTheme.typography.bodyLarge,
|
||
color = colors.textMuted,
|
||
modifier = Modifier.padding(vertical = 40.dp)
|
||
)
|
||
}
|
||
}
|
||
|
||
Spacer(Modifier.height(12.dp))
|
||
|
||
// Атрибуция LRCLIB
|
||
Text(
|
||
text = "Тексты: LRCLIB",
|
||
style = MaterialTheme.typography.labelSmall,
|
||
color = colors.textMuted,
|
||
modifier = Modifier
|
||
.align(Alignment.CenterHorizontally)
|
||
.padding(bottom = 16.dp)
|
||
)
|
||
}
|
||
}
|