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:
parent
581487a29d
commit
89c291e11e
@ -93,6 +93,8 @@ fun MainScreen(
|
|||||||
) {
|
) {
|
||||||
if (uiState.serverAddress.isBlank()) {
|
if (uiState.serverAddress.isBlank()) {
|
||||||
NoServerConfigured(onNavigateToSettings)
|
NoServerConfigured(onNavigateToSettings)
|
||||||
|
} else if (!uiState.isConnected && uiState.isConnecting) {
|
||||||
|
ConnectingIndicator()
|
||||||
} else if (!uiState.isConnected) {
|
} else if (!uiState.isConnected) {
|
||||||
ConnectionError(
|
ConnectionError(
|
||||||
errorMessage = uiState.errorMessage,
|
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
|
@Composable
|
||||||
private fun ConnectionError(
|
private fun ConnectionError(
|
||||||
errorMessage: String?,
|
errorMessage: String?,
|
||||||
|
|||||||
@ -22,6 +22,7 @@ import javax.inject.Inject
|
|||||||
data class MainUiState(
|
data class MainUiState(
|
||||||
val isLoading: Boolean = false,
|
val isLoading: Boolean = false,
|
||||||
val isConnected: Boolean = false,
|
val isConnected: Boolean = false,
|
||||||
|
val isConnecting: Boolean = true, // Show loading while waiting for connection
|
||||||
val errorMessage: String? = null,
|
val errorMessage: String? = null,
|
||||||
val serverAddress: String = "",
|
val serverAddress: String = "",
|
||||||
val karadioStatus: KaradioStatus = KaradioStatus(),
|
val karadioStatus: KaradioStatus = KaradioStatus(),
|
||||||
@ -43,16 +44,24 @@ class MainViewModel @Inject constructor(
|
|||||||
|
|
||||||
private var pollingJob: Job? = null
|
private var pollingJob: Job? = null
|
||||||
private var lastStationName: String? = 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 {
|
init {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
settingsRepository.settings.collect { settings ->
|
settingsRepository.settings.collect { settings ->
|
||||||
_uiState.update { it.copy(serverAddress = settings.serverAddress) }
|
_uiState.update { it.copy(serverAddress = settings.serverAddress) }
|
||||||
if (settings.serverAddress.isNotBlank()) {
|
if (settings.serverAddress.isNotBlank()) {
|
||||||
|
// Reset failure tracking when server address changes
|
||||||
|
connectionFailedSince = null
|
||||||
|
_uiState.update { it.copy(isConnecting = true, errorMessage = null) }
|
||||||
startPolling()
|
startPolling()
|
||||||
} else {
|
} else {
|
||||||
stopPolling()
|
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)
|
karadioRepository.getStatus(serverAddress)
|
||||||
.onSuccess { status ->
|
.onSuccess { status ->
|
||||||
|
// Connection successful - reset failure tracking
|
||||||
|
connectionFailedSince = null
|
||||||
_uiState.update {
|
_uiState.update {
|
||||||
it.copy(
|
it.copy(
|
||||||
isConnected = true,
|
isConnected = true,
|
||||||
|
isConnecting = false,
|
||||||
errorMessage = null,
|
errorMessage = null,
|
||||||
karadioStatus = status
|
karadioStatus = status
|
||||||
)
|
)
|
||||||
@ -95,10 +107,23 @@ class MainViewModel @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.onFailure { error ->
|
.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 {
|
_uiState.update {
|
||||||
it.copy(
|
it.copy(
|
||||||
isConnected = false,
|
isConnected = false,
|
||||||
errorMessage = "Connection failed: ${error.localizedMessage}"
|
isConnecting = !shouldShowError,
|
||||||
|
errorMessage = if (shouldShowError) {
|
||||||
|
"Connection failed: ${error.localizedMessage}"
|
||||||
|
} else null
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user