diff --git a/common/src/main/java/io/homeassistant/companion/android/util/FlowUtil.kt b/common/src/main/java/io/homeassistant/companion/android/util/FlowUtil.kt new file mode 100644 index 000000000..351d058f5 --- /dev/null +++ b/common/src/main/java/io/homeassistant/companion/android/util/FlowUtil.kt @@ -0,0 +1,20 @@ +package io.homeassistant.companion.android.util + +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.conflate +import kotlinx.coroutines.flow.transform + +/** + * Emit the first value from a Flow, and then after the period has passed the last item emitted + * by the Flow during that period (if different). This ensures throttling/debouncing but also + * always receiving the first and last item of the Flow. + * + * From https://github.com/Kotlin/kotlinx.coroutines/issues/1446#issuecomment-1198103541 + */ +fun Flow.throttleLatest(delayMillis: Long): Flow = this + .conflate() + .transform { + emit(it) + delay(delayMillis) + } diff --git a/wear/src/main/java/io/homeassistant/companion/android/home/MainViewModel.kt b/wear/src/main/java/io/homeassistant/companion/android/home/MainViewModel.kt index 8779b24bc..74565fd12 100644 --- a/wear/src/main/java/io/homeassistant/companion/android/home/MainViewModel.kt +++ b/wear/src/main/java/io/homeassistant/companion/android/home/MainViewModel.kt @@ -29,6 +29,7 @@ import io.homeassistant.companion.android.database.wear.getAll import io.homeassistant.companion.android.database.wear.getAllFlow import io.homeassistant.companion.android.sensors.SensorReceiver import io.homeassistant.companion.android.util.RegistriesDataHandler +import io.homeassistant.companion.android.util.throttleLatest import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async import kotlinx.coroutines.flow.Flow @@ -217,7 +218,7 @@ class MainViewModel @Inject constructor( if (!homePresenter.isConnected() || isFavoritesOnly) { return } - homePresenter.getAreaRegistryUpdates()?.collect { + homePresenter.getAreaRegistryUpdates()?.throttleLatest(1000)?.collect { areaRegistry = homePresenter.getAreaRegistry() areas.clear() areaRegistry?.let { @@ -231,7 +232,7 @@ class MainViewModel @Inject constructor( if (!homePresenter.isConnected() || isFavoritesOnly) { return } - homePresenter.getDeviceRegistryUpdates()?.collect { + homePresenter.getDeviceRegistryUpdates()?.throttleLatest(1000)?.collect { deviceRegistry = homePresenter.getDeviceRegistry() updateEntityDomains() } @@ -241,7 +242,7 @@ class MainViewModel @Inject constructor( if (!homePresenter.isConnected()) { return } - homePresenter.getEntityRegistryUpdates()?.collect { + homePresenter.getEntityRegistryUpdates()?.throttleLatest(1000)?.collect { entityRegistry = homePresenter.getEntityRegistry() _supportedEntities.value = getSupportedEntities() updateEntityDomains()