Show loading indicator while connecting, delay error display

Display a CircularProgressIndicator with "Connecting..." text during
initial connection attempts. Only show the connection error message
after 10 seconds of failed attempts to improve user experience.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Pavel Baksy 2025-11-21 17:01:10 +01:00
parent 4fcbbe14f6
commit b659bb7291
2 changed files with 49 additions and 2 deletions

View File

@ -93,6 +93,8 @@ fun MainScreen(
) {
if (uiState.serverAddress.isBlank()) {
NoServerConfigured(onNavigateToSettings)
} else if (!uiState.isConnected && uiState.isConnecting) {
ConnectingIndicator()
} else if (!uiState.isConnected) {
ConnectionError(
errorMessage = uiState.errorMessage,
@ -159,6 +161,26 @@ private fun NoServerConfigured(onNavigateToSettings: () -> Unit) {
}
}
@Composable
private fun ConnectingIndicator() {
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
CircularProgressIndicator(
modifier = Modifier.size(64.dp),
color = MaterialTheme.colorScheme.primary
)
Spacer(modifier = Modifier.height(16.dp))
Text(
text = "Connecting...",
style = MaterialTheme.typography.headlineSmall,
fontWeight = FontWeight.Bold
)
}
}
@Composable
private fun ConnectionError(
errorMessage: String?,

View File

@ -22,6 +22,7 @@ import javax.inject.Inject
data class MainUiState(
val isLoading: Boolean = false,
val isConnected: Boolean = false,
val isConnecting: Boolean = true, // Show loading while waiting for connection
val errorMessage: String? = null,
val serverAddress: String = "",
val karadioStatus: KaradioStatus = KaradioStatus(),
@ -43,16 +44,24 @@ class MainViewModel @Inject constructor(
private var pollingJob: Job? = null
private var lastStationName: String? = null
private var connectionFailedSince: Long? = null
companion object {
private const val ERROR_DISPLAY_DELAY_MS = 10_000L // 10 seconds
}
init {
viewModelScope.launch {
settingsRepository.settings.collect { settings ->
_uiState.update { it.copy(serverAddress = settings.serverAddress) }
if (settings.serverAddress.isNotBlank()) {
// Reset failure tracking when server address changes
connectionFailedSince = null
_uiState.update { it.copy(isConnecting = true, errorMessage = null) }
startPolling()
} else {
stopPolling()
_uiState.update { it.copy(isConnected = false) }
_uiState.update { it.copy(isConnected = false, isConnecting = false) }
}
}
}
@ -80,9 +89,12 @@ class MainViewModel @Inject constructor(
karadioRepository.getStatus(serverAddress)
.onSuccess { status ->
// Connection successful - reset failure tracking
connectionFailedSince = null
_uiState.update {
it.copy(
isConnected = true,
isConnecting = false,
errorMessage = null,
karadioStatus = status
)
@ -95,10 +107,23 @@ class MainViewModel @Inject constructor(
}
}
.onFailure { error ->
val now = System.currentTimeMillis()
// Start tracking failure time if this is the first failure
if (connectionFailedSince == null) {
connectionFailedSince = now
}
val failureDuration = now - (connectionFailedSince ?: now)
val shouldShowError = failureDuration >= ERROR_DISPLAY_DELAY_MS
_uiState.update {
it.copy(
isConnected = false,
errorMessage = "Connection failed: ${error.localizedMessage}"
isConnecting = !shouldShowError,
errorMessage = if (shouldShowError) {
"Connection failed: ${error.localizedMessage}"
} else null
)
}
}