From 810fb3b77a02ffcc8a24bcf3e4dbed2882c89b1a Mon Sep 17 00:00:00 2001 From: andrekir Date: Mon, 1 Apr 2024 19:22:58 -0300 Subject: [PATCH] refactor: add fixed position admin messages --- .../mesh/model/RadioConfigViewModel.kt | 17 +++++++---------- .../datastore/RadioConfigRepository.kt | 1 + .../com/geeksville/mesh/service/MeshService.kt | 13 ++++++++++++- .../mesh/ui/DeviceSettingsFragment.kt | 17 +++++++++++++---- 4 files changed, 33 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/com/geeksville/mesh/model/RadioConfigViewModel.kt b/app/src/main/java/com/geeksville/mesh/model/RadioConfigViewModel.kt index 0d945503b..6e4adc9d5 100644 --- a/app/src/main/java/com/geeksville/mesh/model/RadioConfigViewModel.kt +++ b/app/src/main/java/com/geeksville/mesh/model/RadioConfigViewModel.kt @@ -70,8 +70,8 @@ class RadioConfigViewModel @Inject constructor( // A map from nodeNum to NodeInfo val nodes: StateFlow> get() = radioConfigRepository.nodeDBbyNum - private val _myNodeInfo = MutableStateFlow(null) - val myNodeInfo get() = _myNodeInfo + val myNodeInfo: StateFlow get() = radioConfigRepository.myNodeInfo + val ourNodeInfo: StateFlow get() = radioConfigRepository.ourNodeInfo private val requestIds = MutableStateFlow>(hashMapOf()) private val _radioConfigState = MutableStateFlow(RadioConfigState()) @@ -81,10 +81,6 @@ class RadioConfigViewModel @Inject constructor( val currentDeviceProfile get() = _currentDeviceProfile.value init { - radioConfigRepository.myNodeInfoFlow().onEach { - _myNodeInfo.value = it - }.launchIn(viewModelScope) - radioConfigRepository.deviceProfileFlow.onEach { _currentDeviceProfile.value = it }.launchIn(viewModelScope) @@ -100,7 +96,6 @@ class RadioConfigViewModel @Inject constructor( val myNodeNum get() = myNodeInfo.value?.myNodeNum val maxChannels get() = myNodeInfo.value?.maxChannels ?: 8 - private val ourNodeInfo: NodeInfo? get() = nodes.value[myNodeNum] override fun onCleared() { super.onCleared() @@ -263,14 +258,16 @@ class RadioConfigViewModel @Inject constructor( "Request NodeDB reset error" ) - fun requestPosition(destNum: Int, position: Position = Position(0.0, 0.0, 0)) { + fun setFixedPosition(position: Position) { try { - meshService?.requestPosition(destNum, position) + meshService?.requestPosition(myNodeNum ?: return, position) } catch (ex: RemoteException) { errormsg("Request position error: ${ex.message}") } } + fun removeFixedPosition() = setFixedPosition(Position(0.0, 0.0, 0)) + // Set the radio config (also updates our saved copy in preferences) fun setConfig(config: ConfigProtos.Config) { setRemoteConfig(myNodeNum ?: return, config) @@ -323,7 +320,7 @@ class RadioConfigViewModel @Inject constructor( fun installProfile(protobuf: DeviceProfile) = with(protobuf) { _deviceProfile.value = null // meshService?.beginEditSettings() - if (hasLongName() || hasShortName()) ourNodeInfo?.user?.let { + if (hasLongName() || hasShortName()) ourNodeInfo.value?.user?.let { val user = it.copy( longName = if (hasLongName()) longName else it.longName, shortName = if (hasShortName()) shortName else it.shortName 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 94ed57f44..49e6fa1e1 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 @@ -45,6 +45,7 @@ class RadioConfigRepository @Inject constructor( fun myNodeInfoFlow(): Flow = nodeDB.myNodeInfoFlow() suspend fun getMyNodeInfo(): MyNodeInfo? = myNodeInfoFlow().firstOrNull() val myNodeInfo: StateFlow get() = nodeDB.myNodeInfo + val ourNodeInfo: StateFlow get() = nodeDB.ourNodeInfo val nodeDBbyNum: StateFlow> get() = nodeDB.nodeDBbyNum val nodeDBbyID: StateFlow> get() = nodeDB.nodeDBbyID 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 20f8797d0..b154e86e2 100644 --- a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt +++ b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt @@ -1864,13 +1864,24 @@ class MeshService : Service(), Logging { } override fun requestPosition(destNum: Int, position: Position) = toRemoteExceptions { - if (position == Position(0.0, 0.0, 0)) { + if (destNum != myNodeNum) { // request position sendPosition(destNum = destNum, wantResponse = true) } else { // send fixed position (local only/no remote method, so we force destNum to null) val (lat, lon, alt) = position sendPosition(destNum = null, lat = lat, lon = lon, alt = alt) + sendToRadio(newMeshPacketTo(destNum).buildAdminPacket { + if (position != Position(0.0, 0.0, 0)) { + setFixedPosition = position { + longitudeI = Position.degI(lon) + latitudeI = Position.degI(lat) + altitude = alt + } + } else { + removeFixedPosition = true + } + }) } } diff --git a/app/src/main/java/com/geeksville/mesh/ui/DeviceSettingsFragment.kt b/app/src/main/java/com/geeksville/mesh/ui/DeviceSettingsFragment.kt index eb5b51a4d..4e96edbb6 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/DeviceSettingsFragment.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/DeviceSettingsFragment.kt @@ -194,6 +194,8 @@ sealed class ResponseState { data class Loading(var total: Int = 1, var completed: Int = 0) : ResponseState() data class Success(val result: T) : ResponseState() data class Error(val error: String) : ResponseState() + + fun isWaiting() = this !is Empty } @Composable @@ -237,7 +239,7 @@ fun RadioConfigNavHost( var location by remember(node) { mutableStateOf(node?.position) } // FIXME val deviceProfile by viewModel.deviceProfile.collectAsStateWithLifecycle() - val isWaiting = radioConfigState.responseState !is ResponseState.Empty + val isWaiting = radioConfigState.responseState.isWaiting() var showEditDeviceProfileDialog by remember { mutableStateOf(false) } val importConfigLauncher = rememberLauncherForActivityResult( @@ -401,9 +403,16 @@ fun RadioConfigNavHost( positionConfig = radioConfigState.radioConfig.position, enabled = connected, onSaveClicked = { locationInput, positionInput -> - if (locationInput != location && positionInput.fixedPosition) { - locationInput?.let { viewModel.requestPosition(destNum, it) } - location = locationInput + if (positionInput.fixedPosition) { + if (locationInput != null && locationInput != location) { + viewModel.setFixedPosition(locationInput) + location = locationInput + } + } else { + if (radioConfigState.radioConfig.position.fixedPosition) { + // fixed position changed from enabled to disabled + viewModel.removeFixedPosition() + } } val config = config { position = positionInput } viewModel.setRemoteConfig(destNum, config)