Fix connection state flapping and bump version to 1.1

Add consecutive failure threshold (3 polls) before marking as
disconnected, preventing UI flapping caused by intermittent ESP32
errors. Bump versionCode to 2 and versionName to 1.1.
This commit is contained in:
vesp 2026-02-16 10:42:19 +01:00
parent b45d4ab473
commit 974c529830
2 changed files with 19 additions and 10 deletions

View File

@ -32,8 +32,8 @@ android {
applicationId = "cz.bugsy.karemote"
minSdk = 33
targetSdk = 36
versionCode = 1
versionName = "1.0"
versionCode = 2
versionName = "1.1"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {

View File

@ -65,6 +65,7 @@ class MainViewModel @Inject constructor(
private var pollingJob: Job? = null
private var lastStationName: String? = null
private var connectionFailedSince: Long? = null
private var consecutiveFailures: Int = 0
private var volumeJob: Job? = null
private var lastVolumeSentTime: Long = 0
private var pendingVolume: Int? = null
@ -72,6 +73,7 @@ class MainViewModel @Inject constructor(
companion object {
private const val ERROR_DISPLAY_DELAY_MS = 10_000L // 10 seconds
private const val VOLUME_THROTTLE_MS = 300L // Throttle volume commands
private const val DISCONNECT_THRESHOLD = 3 // Consecutive failures before marking disconnected
}
init {
@ -81,6 +83,7 @@ class MainViewModel @Inject constructor(
if (settings.serverAddress.isNotBlank()) {
// Reset failure tracking when server address changes
connectionFailedSince = null
consecutiveFailures = 0
_uiState.update { it.copy(isConnecting = true, errorMessage = null) }
startPolling()
} else {
@ -115,6 +118,7 @@ class MainViewModel @Inject constructor(
.onSuccess { status ->
// Connection successful - reset failure tracking
connectionFailedSince = null
consecutiveFailures = 0
_uiState.update {
it.copy(
isConnected = true,
@ -131,6 +135,7 @@ class MainViewModel @Inject constructor(
}
}
.onFailure { error ->
consecutiveFailures++
val now = System.currentTimeMillis()
// Start tracking failure time if this is the first failure
@ -141,14 +146,18 @@ class MainViewModel @Inject constructor(
val failureDuration = now - (connectionFailedSince ?: now)
val shouldShowError = failureDuration >= ERROR_DISPLAY_DELAY_MS
_uiState.update {
it.copy(
isConnected = false,
isConnecting = !shouldShowError,
errorMessage = if (shouldShowError) {
"Connection failed: ${error.localizedMessage}"
} else null
)
// Only mark as disconnected after multiple consecutive failures
// to avoid flapping when ESP32 has intermittent errors
if (consecutiveFailures >= DISCONNECT_THRESHOLD) {
_uiState.update {
it.copy(
isConnected = false,
isConnecting = !shouldShowError,
errorMessage = if (shouldShowError) {
"Connection failed: ${error.localizedMessage}"
} else null
)
}
}
}
}