feat(lyrics): тексты песен внутри приложения через LRCLIB
- LrcLibApi (api/get + api/search, User-Agent), DI @Named(lrclib) Retrofit - LyricsRepository.fetchLyrics -> LyricsResult (plain/synced/instrumental) - LyricsViewModel + LyricsSheet (загрузка/инструментал/найдено/не найдено), прокрутка + атрибуция LRCLIB - кнопка «Текст песни» открывает встроенный экран (плеер + деталь трека чартов), вместо ссылки в браузере
This commit is contained in:
@@ -46,6 +46,7 @@ import com.radiola.ui.components.EmptyState
|
||||
import com.radiola.ui.components.PopularityChart
|
||||
import com.radiola.ui.components.crossfadeModel
|
||||
import com.radiola.ui.components.serviceLogoRes
|
||||
import com.radiola.ui.lyrics.LyricsSheet
|
||||
import com.radiola.ui.theme.Motion
|
||||
import com.radiola.ui.theme.RadiolaTheme
|
||||
import com.radiola.ui.theme.pressScale
|
||||
@@ -163,10 +164,7 @@ fun ChartsScreen(
|
||||
stats = selectedStats,
|
||||
isLoading = isLoadingStats,
|
||||
onDismiss = viewModel::clearSelection,
|
||||
onToggleLike = { viewModel.toggleLike(it) },
|
||||
onLyricsClick = { artist, song ->
|
||||
// Строим URL Musixmatch и открываем в браузере
|
||||
}
|
||||
onToggleLike = { viewModel.toggleLike(it) }
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -360,12 +358,12 @@ private fun TrackDetailSheet(
|
||||
stats: TrackStats?,
|
||||
isLoading: Boolean,
|
||||
onDismiss: () -> Unit,
|
||||
onToggleLike: (String) -> Unit,
|
||||
onLyricsClick: (artist: String, song: String) -> Unit
|
||||
onToggleLike: (String) -> Unit
|
||||
) {
|
||||
val colors = RadiolaTheme.colors
|
||||
val context = LocalContext.current
|
||||
val haptic = LocalHapticFeedback.current
|
||||
var showLyrics by remember { mutableStateOf(false) }
|
||||
|
||||
ModalBottomSheet(
|
||||
onDismissRequest = onDismiss,
|
||||
@@ -486,17 +484,9 @@ private fun TrackDetailSheet(
|
||||
|
||||
Spacer(Modifier.height(20.dp))
|
||||
|
||||
// Кнопка «Текст песни»
|
||||
// Кнопка «Текст песни» — открывает встроенный экран
|
||||
OutlinedButton(
|
||||
onClick = {
|
||||
// Строим URL Musixmatch и открываем в браузере
|
||||
val query = java.net.URLEncoder.encode(
|
||||
"${stats.artist} ${stats.song}", "UTF-8"
|
||||
)
|
||||
val url = "https://www.musixmatch.com/search/$query"
|
||||
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
|
||||
context.startActivity(intent)
|
||||
},
|
||||
onClick = { showLyrics = true },
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
shape = RoundedCornerShape(12.dp),
|
||||
colors = ButtonDefaults.outlinedButtonColors(
|
||||
@@ -542,6 +532,20 @@ private fun TrackDetailSheet(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Шторка текста песни поверх детальной карточки
|
||||
if (showLyrics && stats != null) {
|
||||
ModalBottomSheet(
|
||||
onDismissRequest = { showLyrics = false },
|
||||
containerColor = colors.bgBase,
|
||||
sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
|
||||
) {
|
||||
LyricsSheet(
|
||||
artist = stats.artist,
|
||||
song = stats.song
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ---- Метрики трека ----
|
||||
|
||||
Reference in New Issue
Block a user