feat(stations): обложка текущего трека на карточке станции + подпись

Для станций без своей обложки (и для Radio Record — единый стиль) карточка
показывает обложку играющего трека с тёмным градиентом и подписью трек/исполнитель.
Источник — /now-playing (теперь с name станции), матч по имени, обновление 20с.
Приоритет: трек -> логотип станции -> фирменная плитка.
This commit is contained in:
nk
2026-06-03 12:18:19 +03:00
parent 9d115b148e
commit ee689ce380
8 changed files with 129 additions and 27 deletions

View File

@@ -7,6 +7,7 @@ import kotlinx.serialization.Serializable
@Serializable
data class BackendNowPlayingDto(
@SerialName("stationId") val stationId: Int,
@SerialName("name") val name: String = "",
@SerialName("song") val song: String,
@SerialName("artist") val artist: String,
@SerialName("coverUrl") val coverUrl: String? = null

View File

@@ -16,6 +16,10 @@ class NowPlayingRepositoryImpl @Inject constructor(
private val _nowPlaying = MutableStateFlow<Map<Int, Track>>(emptyMap())
// Карта по lowercase-имени станции: заполняется при REST-поллинге,
// используется для матчинга карточек (id локальных станций может отличаться).
private val _nowPlayingByName = MutableStateFlow<Map<String, Track>>(emptyMap())
init {
socketClient.connect()
}
@@ -34,6 +38,8 @@ class NowPlayingRepositoryImpl @Inject constructor(
restMap + socketMap
}
override fun getAllNowPlayingByName(): Flow<Map<String, Track>> = _nowPlayingByName
override suspend fun refreshNowPlaying(): Result<Unit> {
return try {
// Берём now-playing с нашего бэкенда: там корректный маппинг
@@ -45,9 +51,20 @@ class NowPlayingRepositoryImpl @Inject constructor(
artist = dto.artist,
song = dto.song,
coverUrl = dto.coverUrl,
stationName = ""
stationName = dto.name
)
}
// Параллельный индекс по имени — для матчинга карточек станций.
_nowPlayingByName.value = list
.filter { it.name.isNotBlank() }
.associate { dto ->
dto.name.trim().lowercase() to Track(
artist = dto.artist,
song = dto.song,
coverUrl = dto.coverUrl,
stationName = dto.name
)
}
Result.success(Unit)
} catch (e: Exception) {
Result.failure(e)