Throttle volume commands to prevent ESP32 overload
Limits volume API calls to max 1 per 300ms while dragging the slider. UI updates remain immediate for smooth feedback, and the final value is always sent when the user stops adjusting.
This commit is contained in:
parent
bc2d40d132
commit
f9adf3d3db
@ -47,9 +47,13 @@ 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
|
private var connectionFailedSince: Long? = null
|
||||||
|
private var volumeJob: Job? = null
|
||||||
|
private var lastVolumeSentTime: Long = 0
|
||||||
|
private var pendingVolume: Int? = null
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val ERROR_DISPLAY_DELAY_MS = 10_000L // 10 seconds
|
private const val ERROR_DISPLAY_DELAY_MS = 10_000L // 10 seconds
|
||||||
|
private const val VOLUME_THROTTLE_MS = 300L // Throttle volume commands
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@ -161,15 +165,35 @@ class MainViewModel @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun setVolume(volume: Int) {
|
fun setVolume(volume: Int) {
|
||||||
viewModelScope.launch {
|
val serverAddress = _uiState.value.serverAddress
|
||||||
val serverAddress = _uiState.value.serverAddress
|
if (serverAddress.isBlank()) return
|
||||||
if (serverAddress.isBlank()) return@launch
|
|
||||||
|
|
||||||
// Optimistically update UI
|
// Always update UI immediately for smooth feedback
|
||||||
_uiState.update {
|
_uiState.update {
|
||||||
it.copy(karadioStatus = it.karadioStatus.copy(volume = volume))
|
it.copy(karadioStatus = it.karadioStatus.copy(volume = volume))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Throttle network calls
|
||||||
|
val now = System.currentTimeMillis()
|
||||||
|
pendingVolume = volume
|
||||||
|
|
||||||
|
if (now - lastVolumeSentTime >= VOLUME_THROTTLE_MS) {
|
||||||
|
// Enough time has passed, send immediately
|
||||||
|
sendVolumeToDevice(serverAddress, volume)
|
||||||
|
} else {
|
||||||
|
// Schedule a delayed send for the pending value
|
||||||
|
volumeJob?.cancel()
|
||||||
|
volumeJob = viewModelScope.launch {
|
||||||
|
delay(VOLUME_THROTTLE_MS - (now - lastVolumeSentTime))
|
||||||
|
pendingVolume?.let { sendVolumeToDevice(serverAddress, it) }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun sendVolumeToDevice(serverAddress: String, volume: Int) {
|
||||||
|
lastVolumeSentTime = System.currentTimeMillis()
|
||||||
|
pendingVolume = null
|
||||||
|
viewModelScope.launch {
|
||||||
karadioRepository.setVolume(serverAddress, volume)
|
karadioRepository.setVolume(serverAddress, volume)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user