From a12c5052bc2b8d83f0734942020c9621c9ca3329 Mon Sep 17 00:00:00 2001 From: andrekir Date: Wed, 1 May 2024 09:23:54 -0300 Subject: [PATCH] refactor: improve connection status feedback using new `wantConfig` state --- .../java/com/geeksville/mesh/model/UIState.kt | 2 ++ .../datastore/RadioConfigRepository.kt | 23 ++++++++++++ .../geeksville/mesh/service/MeshService.kt | 5 +++ .../mesh/service/ServiceRepository.kt | 14 ++++++++ .../geeksville/mesh/ui/SettingsFragment.kt | 36 ++++++++----------- 5 files changed, 58 insertions(+), 22 deletions(-) diff --git a/app/src/main/java/com/geeksville/mesh/model/UIState.kt b/app/src/main/java/com/geeksville/mesh/model/UIState.kt index cf4a57f2..52df248c 100644 --- a/app/src/main/java/com/geeksville/mesh/model/UIState.kt +++ b/app/src/main/java/com/geeksville/mesh/model/UIState.kt @@ -115,6 +115,8 @@ class UIViewModel @Inject constructor( val bondedAddress get() = radioInterfaceService.getBondedDeviceAddress() val selectedBluetooth get() = radioInterfaceService.getDeviceAddress()?.getOrNull(0) == 'x' + val wantConfigState get() = radioConfigRepository.wantConfigState + private val _packets = MutableStateFlow>(emptyList()) val packets: StateFlow> = _packets diff --git a/app/src/main/java/com/geeksville/mesh/repository/datastore/RadioConfigRepository.kt b/app/src/main/java/com/geeksville/mesh/repository/datastore/RadioConfigRepository.kt index 77b6df16..1fe986b7 100644 --- a/app/src/main/java/com/geeksville/mesh/repository/datastore/RadioConfigRepository.kt +++ b/app/src/main/java/com/geeksville/mesh/repository/datastore/RadioConfigRepository.kt @@ -17,6 +17,7 @@ import com.geeksville.mesh.model.NodeDB import com.geeksville.mesh.model.getChannelUrl import com.geeksville.mesh.service.MeshService.ConnectionState import com.geeksville.mesh.service.ServiceRepository +import com.geeksville.mesh.service.WantConfigState import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.SharedFlow @@ -38,6 +39,28 @@ class RadioConfigRepository @Inject constructor( ) { val meshService: IMeshService? get() = serviceRepository.meshService + val wantConfigState: StateFlow = serviceRepository.wantConfigState + + fun clearWantConfigState() { + serviceRepository.setWantConfigState { WantConfigState() } + } + + fun increaseNodeCount() { + serviceRepository.setWantConfigState { it.copy(nodeCount = it.nodeCount + 1) } + } + + fun increaseChannelCount() { + serviceRepository.setWantConfigState { it.copy(channelCount = it.channelCount + 1) } + } + + fun increaseConfigCount() { + serviceRepository.setWantConfigState { it.copy(configCount = it.configCount + 1) } + } + + fun increaseModuleCount() { + serviceRepository.setWantConfigState { it.copy(moduleCount = it.moduleCount + 1) } + } + // Connection state to our radio device val connectionState get() = serviceRepository.connectionState fun setConnectionState(state: ConnectionState) = serviceRepository.setConnectionState(state) diff --git a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt index 1dce9eb1..cab8a51a 100644 --- a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt +++ b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt @@ -1255,6 +1255,7 @@ class MeshService : Service(), Logging { ) insertMeshLog(packetToSave) setLocalConfig(config) + radioConfigRepository.increaseConfigCount() } private fun handleModuleConfig(config: ModuleConfigProtos.ModuleConfig) { @@ -1267,6 +1268,7 @@ class MeshService : Service(), Logging { ) insertMeshLog(packetToSave) setLocalModuleConfig(config) + radioConfigRepository.increaseModuleCount() } private fun handleQueueStatus(queueStatus: MeshProtos.QueueStatus) { @@ -1289,6 +1291,7 @@ class MeshService : Service(), Logging { ) insertMeshLog(packetToSave) if (ch.role != ChannelProtos.Channel.Role.DISABLED) updateChannelSettings(ch) + radioConfigRepository.increaseChannelCount() } /** @@ -1330,6 +1333,7 @@ class MeshService : Service(), Logging { insertMeshLog(packetToSave) newNodes.add(info) + radioConfigRepository.increaseNodeCount() } @@ -1540,6 +1544,7 @@ class MeshService : Service(), Logging { configNonce += 1 newNodes.clear() newMyNodeInfo = null + radioConfigRepository.clearWantConfigState() if (BluetoothInterface.invalidVersion) onHasSettings() // Device firmware is too old diff --git a/app/src/main/java/com/geeksville/mesh/service/ServiceRepository.kt b/app/src/main/java/com/geeksville/mesh/service/ServiceRepository.kt index ab63704d..ced54fe6 100644 --- a/app/src/main/java/com/geeksville/mesh/service/ServiceRepository.kt +++ b/app/src/main/java/com/geeksville/mesh/service/ServiceRepository.kt @@ -7,9 +7,17 @@ import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.updateAndGet import javax.inject.Inject import javax.inject.Singleton +data class WantConfigState( + var nodeCount: Int = 0, + var channelCount: Int = 0, + var configCount: Int = 0, + var moduleCount: Int = 0, +) + /** * Repository class for managing the [IMeshService] instance and connection state */ @@ -42,6 +50,12 @@ class ServiceRepository @Inject constructor() : Logging { _errorMessage.value = null } + private val _wantConfigState = MutableStateFlow(WantConfigState()) + val wantConfigState: StateFlow = _wantConfigState + + fun setWantConfigState(update: (old: WantConfigState) -> WantConfigState): WantConfigState = + _wantConfigState.updateAndGet(update) + private val _meshPacketFlow = MutableSharedFlow() val meshPacketFlow: SharedFlow get() = _meshPacketFlow diff --git a/app/src/main/java/com/geeksville/mesh/ui/SettingsFragment.kt b/app/src/main/java/com/geeksville/mesh/ui/SettingsFragment.kt index 847553f6..c366a83b 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/SettingsFragment.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/SettingsFragment.kt @@ -188,32 +188,24 @@ class SettingsFragment : ScreenFragment("Settings"), Logging { updateNodeInfo() } - model.localConfig.asLiveData().observe(viewLifecycleOwner) { - if (!model.isConnected()) { - val configCount = it.allFields.size - val configTotal = ConfigProtos.Config.getDescriptor().fields.size - if (configCount > 0) - scanModel.setErrorText("Device config ($configCount / $configTotal)") - } else updateNodeInfo() - } + model.wantConfigState.asLiveData().observe(viewLifecycleOwner) { + if (model.isConnected()) return@observe + val configTotal = ConfigProtos.Config.getDescriptor().fields.size + val moduleTotal = ModuleConfigProtos.ModuleConfig.getDescriptor().fields.size - model.moduleConfig.asLiveData().observe(viewLifecycleOwner) { - if (!model.isConnected()) { - val moduleCount = it.allFields.size - val moduleTotal = ModuleConfigProtos.ModuleConfig.getDescriptor().fields.size - if (moduleCount > 0) - scanModel.setErrorText("Module config ($moduleCount / $moduleTotal)") - } else updateNodeInfo() - } - - model.channels.asLiveData().observe(viewLifecycleOwner) { - if (!model.isConnected()) { - val maxChannels = model.maxChannels - if (!it.hasLoraConfig() && it.settingsCount > 0) - scanModel.setErrorText("Channels (${it.settingsCount} / $maxChannels)") + binding.scanStatusText.text = when { + it.moduleCount > 0 -> "Module config (${it.moduleCount} / $moduleTotal)" + it.configCount > 0 -> "Device config (${it.configCount} / $configTotal)" + it.channelCount > 0 -> "Channels (${it.channelCount} / ${model.maxChannels})" + it.nodeCount > 0 -> "Nodes (${it.nodeCount} / 100)" + else -> return@observe } } + model.localConfig.asLiveData().observe(viewLifecycleOwner) { + if (model.isConnected()) updateNodeInfo() + } + // Also watch myNodeInfo because it might change later model.myNodeInfo.asLiveData().observe(viewLifecycleOwner) { updateNodeInfo()