feat(stations): свайп по списку листает чипы + свечение играющей станции

1) Горизонтальный свайп по области списка переключает фильтры-чипы в их
   порядке ([Все]+жанры), выбранный чип автоскроллится в зону видимости.
   Вертикальная прокрутка грида сохраняется.

2) У играющей станции в списке — мягкое радиальное свечение позади обложки,
   которое «гуляет» (двигается центр) и вылезает из-под краёв, + эквалайзер-
   бейдж в углу. Источник активной станции — PlayerController.currentStationId.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
nk
2026-06-04 14:12:01 +03:00
parent 603e232dff
commit 9268e14cc6
6 changed files with 169 additions and 9 deletions

View File

@@ -32,6 +32,10 @@ class PlayerController @Inject constructor(
private val _currentStationPrefix = MutableStateFlow<String?>(null)
val currentStationPrefix: StateFlow<String?> = _currentStationPrefix
// Id играющей станции — для подсветки активной карточки в списке.
private val _currentStationId = MutableStateFlow<Int?>(null)
val currentStationId: StateFlow<Int?> = _currentStationId
private val _icyTitle = MutableStateFlow<String?>(null)
val icyTitle: StateFlow<String?> = _icyTitle.asStateFlow()
@@ -136,8 +140,9 @@ class PlayerController @Inject constructor(
audioManager.registerAudioDeviceCallback(audioDeviceCallback, null)
}
fun play(url: String, stationPrefix: String, stationName: String) {
fun play(url: String, stationPrefix: String, stationName: String, stationId: Int? = null) {
Log.d("PlayerController", "play() called with url=$url prefix=$stationPrefix")
_currentStationId.value = stationId
_icyTitle.value = null
val mediaItem = MediaItem.Builder()
.setUri(url)
@@ -193,6 +198,7 @@ class PlayerController @Inject constructor(
fun stop() {
exoPlayer.stop()
_currentStationPrefix.value = null
_currentStationId.value = null
}
fun release() {