From c792e247741286c45dbd82cc539dca00570edad6 Mon Sep 17 00:00:00 2001 From: Pavel Baksy Date: Sat, 22 Nov 2025 23:26:06 +0100 Subject: [PATCH] Improve station picker with favicons and fix indexing - Fix station list starting at index 0 instead of 1 - Fetch and display station favicons from RadioBrowser - Remove redundant "Station X" text from list items --- .../karemote/data/model/KaradioModels.kt | 3 +- .../data/repository/KaradioRepository.kt | 2 +- .../karemote/ui/screens/main/MainScreen.kt | 30 ++++++++++++------- .../karemote/ui/screens/main/MainViewModel.kt | 13 ++++++++ 4 files changed, 36 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/cz/bugsy/karemote/data/model/KaradioModels.kt b/app/src/main/java/cz/bugsy/karemote/data/model/KaradioModels.kt index 9eb3f52..8a2bd3c 100644 --- a/app/src/main/java/cz/bugsy/karemote/data/model/KaradioModels.kt +++ b/app/src/main/java/cz/bugsy/karemote/data/model/KaradioModels.kt @@ -14,7 +14,8 @@ data class KaradioStation( val url: String, val path: String, val port: Int, - val volumeOffset: Int = 0 + val volumeOffset: Int = 0, + val favicon: String? = null ) fun parseKaradioStatus(response: String): KaradioStatus { diff --git a/app/src/main/java/cz/bugsy/karemote/data/repository/KaradioRepository.kt b/app/src/main/java/cz/bugsy/karemote/data/repository/KaradioRepository.kt index 033b59c..7ca81f6 100644 --- a/app/src/main/java/cz/bugsy/karemote/data/repository/KaradioRepository.kt +++ b/app/src/main/java/cz/bugsy/karemote/data/repository/KaradioRepository.kt @@ -99,7 +99,7 @@ class KaradioRepository @Inject constructor() { withContext(Dispatchers.IO) { runCatching { val stations = mutableListOf() - for (i in 1 until maxStations) { + for (i in 0 until maxStations) { val response = getApi(serverAddress).getStationName(i) val name = parseStationNameResponse(response) if (name.isNotBlank() && name != "not set") { diff --git a/app/src/main/java/cz/bugsy/karemote/ui/screens/main/MainScreen.kt b/app/src/main/java/cz/bugsy/karemote/ui/screens/main/MainScreen.kt index 5aa1cb6..0e3206a 100644 --- a/app/src/main/java/cz/bugsy/karemote/ui/screens/main/MainScreen.kt +++ b/app/src/main/java/cz/bugsy/karemote/ui/screens/main/MainScreen.kt @@ -499,7 +499,6 @@ private fun StationPickerSheet( items(stations) { station -> ListItem( headlineContent = { Text(station.name) }, - supportingContent = { Text("Station ${station.index}") }, leadingContent = { Box( modifier = Modifier @@ -513,15 +512,26 @@ private fun StationPickerSheet( ), contentAlignment = Alignment.Center ) { - Icon( - imageVector = Icons.Default.Radio, - contentDescription = null, - tint = if (station.index == currentStation) - MaterialTheme.colorScheme.onPrimary - else - MaterialTheme.colorScheme.onPrimaryContainer, - modifier = Modifier.size(24.dp) - ) + if (!station.favicon.isNullOrBlank()) { + AsyncImage( + model = station.favicon, + contentDescription = "Station logo", + modifier = Modifier + .size(40.dp) + .clip(CircleShape), + contentScale = ContentScale.Crop + ) + } else { + Icon( + imageVector = Icons.Default.Radio, + contentDescription = null, + tint = if (station.index == currentStation) + MaterialTheme.colorScheme.onPrimary + else + MaterialTheme.colorScheme.onPrimaryContainer, + modifier = Modifier.size(24.dp) + ) + } } }, modifier = Modifier.clickable { onStationSelected(station.index) } diff --git a/app/src/main/java/cz/bugsy/karemote/ui/screens/main/MainViewModel.kt b/app/src/main/java/cz/bugsy/karemote/ui/screens/main/MainViewModel.kt index fa89a81..d0c4691 100644 --- a/app/src/main/java/cz/bugsy/karemote/ui/screens/main/MainViewModel.kt +++ b/app/src/main/java/cz/bugsy/karemote/ui/screens/main/MainViewModel.kt @@ -10,6 +10,8 @@ import cz.bugsy.karemote.data.repository.RadioBrowserRepository import cz.bugsy.karemote.data.repository.SettingsRepository import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Job +import kotlinx.coroutines.async +import kotlinx.coroutines.awaitAll import kotlinx.coroutines.delay import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow @@ -227,9 +229,20 @@ class MainViewModel @Inject constructor( karadioRepository.getStationList(serverAddress, maxStations = 50) .onSuccess { stations -> + // Show stations immediately, then enrich with favicons _uiState.update { it.copy(stations = stations, isLoadingStations = false) } + + // Fetch favicons from RadioBrowser concurrently + val enrichedStations = stations.map { station -> + async { + val radioBrowserInfo = radioBrowserRepository.getStationInfo(station.name) + station.copy(favicon = radioBrowserInfo?.favicon) + } + }.awaitAll() + + _uiState.update { it.copy(stations = enrichedStations) } } .onFailure { _uiState.update { it.copy(isLoadingStations = false) }