[Fix] Scanner item flicker
This commit is contained in:
+19
-7
@@ -37,6 +37,7 @@ import kotlinx.coroutines.withTimeout
|
||||
import kotlinx.coroutines.TimeoutCancellationException
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlin.time.Duration.Companion.milliseconds
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
import kotlin.time.TimeSource
|
||||
import kotlin.uuid.ExperimentalUuidApi
|
||||
@@ -45,6 +46,10 @@ data class ConnectedDevice(
|
||||
val advertisement: Advertisement,
|
||||
val state: State
|
||||
)
|
||||
data class AdvertisementMark(
|
||||
val advertisement: Advertisement,
|
||||
val timeMark: TimeSource.Monotonic.ValueTimeMark
|
||||
)
|
||||
@OptIn(ExperimentalUuidApi::class)
|
||||
class ScannerViewModel(
|
||||
private val bleManager: BleManager,
|
||||
@@ -54,7 +59,7 @@ class ScannerViewModel(
|
||||
private val scannerRepository: ScannerRepository
|
||||
) : ViewModel() {
|
||||
companion object {
|
||||
private val SCAN_TIMEOUT = 1.seconds
|
||||
private val SCAN_TIMEOUT = 5.seconds
|
||||
private val CONNECTION_TIMEOUT = 5.seconds
|
||||
private const val MAX_LOG_ENTRIES = 50
|
||||
}
|
||||
@@ -79,7 +84,7 @@ class ScannerViewModel(
|
||||
private var cleanupJob: Job? = null
|
||||
private val connectionJobs = mutableMapOf<String, Job>()
|
||||
|
||||
private val advertisementMap = mutableMapOf<String, Pair<Advertisement, TimeSource.Monotonic.ValueTimeMark>>()
|
||||
private val advertisementMap = mutableMapOf<String, AdvertisementMark>()
|
||||
|
||||
/** Bonded device */
|
||||
private val bondedIds = mutableSetOf<String>() // Cache
|
||||
@@ -118,7 +123,12 @@ class ScannerViewModel(
|
||||
connect(advertisement)
|
||||
} else {
|
||||
val now = TimeSource.Monotonic.markNow()
|
||||
advertisementMap[advertisement.identifier.toString()] = advertisement to now
|
||||
val entry = advertisementMap[bleId]
|
||||
if (entry != null) {
|
||||
advertisementMap[bleId] = entry.copy(advertisement = advertisement, timeMark = now)
|
||||
} else {
|
||||
advertisementMap[bleId] = AdvertisementMark(advertisement, now)
|
||||
}
|
||||
startCleanupJob()
|
||||
updateDeviceList()
|
||||
}
|
||||
@@ -131,8 +141,8 @@ class ScannerViewModel(
|
||||
if (cleanupJob?.isActive == true) return
|
||||
cleanupJob = viewModelScope.launch {
|
||||
while (advertisementMap.isNotEmpty() && isActive) {
|
||||
delay(1000)
|
||||
val keysToRemove = advertisementMap.filter { it.value.second.elapsedNow() > SCAN_TIMEOUT }.keys
|
||||
delay(5000)
|
||||
val keysToRemove = advertisementMap.filter { it.value.timeMark.elapsedNow() > SCAN_TIMEOUT }.keys
|
||||
if (keysToRemove.isNotEmpty()) {
|
||||
keysToRemove.forEach { advertisementMap.remove(it) }
|
||||
updateDeviceList()
|
||||
@@ -147,8 +157,10 @@ class ScannerViewModel(
|
||||
}
|
||||
|
||||
private fun updateDeviceList() {
|
||||
_devices.value = advertisementMap.values.map { it.first }
|
||||
// .sortedByDescending { it.rssi } // Fix flicker
|
||||
val newList = advertisementMap.values.map { it.advertisement }
|
||||
if (newList != _devices.value) {
|
||||
_devices.value = newList
|
||||
}
|
||||
}
|
||||
|
||||
fun stopScan() {
|
||||
|
||||
Reference in New Issue
Block a user