refactor(config): move `connectionState` to `RadioConfigState`

pull/1375/head
andrekir 2024-10-31 15:35:31 -03:00 zatwierdzone przez Andre K
rodzic 150249ab3e
commit 74ae3fd594
3 zmienionych plików z 69 dodań i 76 usunięć

Wyświetl plik

@ -22,6 +22,7 @@ import com.geeksville.mesh.database.entity.NodeEntity
import com.geeksville.mesh.deviceProfile import com.geeksville.mesh.deviceProfile
import com.geeksville.mesh.moduleConfig import com.geeksville.mesh.moduleConfig
import com.geeksville.mesh.repository.datastore.RadioConfigRepository import com.geeksville.mesh.repository.datastore.RadioConfigRepository
import com.geeksville.mesh.service.MeshService.ConnectionState
import com.geeksville.mesh.ui.AdminRoute import com.geeksville.mesh.ui.AdminRoute
import com.geeksville.mesh.ui.ConfigRoute import com.geeksville.mesh.ui.ConfigRoute
import com.geeksville.mesh.ui.ModuleRoute import com.geeksville.mesh.ui.ModuleRoute
@ -45,6 +46,7 @@ import javax.inject.Inject
* Data class that represents the current RadioConfig state. * Data class that represents the current RadioConfig state.
*/ */
data class RadioConfigState( data class RadioConfigState(
val connected: Boolean = false,
val route: String = "", val route: String = "",
val metadata: MeshProtos.DeviceMetadata = MeshProtos.DeviceMetadata.getDefaultInstance(), val metadata: MeshProtos.DeviceMetadata = MeshProtos.DeviceMetadata.getDefaultInstance(),
val userConfig: MeshProtos.User = MeshProtos.User.getDefaultInstance(), val userConfig: MeshProtos.User = MeshProtos.User.getDefaultInstance(),
@ -66,9 +68,6 @@ class RadioConfigViewModel @Inject constructor(
private val meshService: IMeshService? get() = radioConfigRepository.meshService private val meshService: IMeshService? get() = radioConfigRepository.meshService
// Connection state to our radio device
val connectionState get() = radioConfigRepository.connectionState
private val _destNum = MutableStateFlow<Int?>(null) private val _destNum = MutableStateFlow<Int?>(null)
private val _destNode = MutableStateFlow<NodeEntity?>(null) private val _destNode = MutableStateFlow<NodeEntity?>(null)
val destNode: StateFlow<NodeEntity?> get() = _destNode val destNode: StateFlow<NodeEntity?> get() = _destNode
@ -100,7 +99,8 @@ class RadioConfigViewModel @Inject constructor(
radioConfigRepository.meshPacketFlow.onEach(::processPacketResponse) radioConfigRepository.meshPacketFlow.onEach(::processPacketResponse)
.launchIn(viewModelScope) .launchIn(viewModelScope)
combine(connectionState, radioConfigState) { connState, configState -> combine(radioConfigRepository.connectionState, radioConfigState) { connState, configState ->
_radioConfigState.update { it.copy(connected = connState == ConnectionState.CONNECTED) }
if (connState.isDisconnected() && configState.responseState.isWaiting()) { if (connState.isDisconnected() && configState.responseState.isWaiting()) {
setResponseStateError(app.getString(R.string.disconnected)) setResponseStateError(app.getString(R.string.disconnected))
} }

Wyświetl plik

@ -63,7 +63,6 @@ import com.geeksville.mesh.model.Channel
import com.geeksville.mesh.model.MetricsViewModel import com.geeksville.mesh.model.MetricsViewModel
import com.geeksville.mesh.model.RadioConfigViewModel import com.geeksville.mesh.model.RadioConfigViewModel
import com.geeksville.mesh.moduleConfig import com.geeksville.mesh.moduleConfig
import com.geeksville.mesh.service.MeshService.ConnectionState
import com.geeksville.mesh.ui.components.DeviceMetricsScreen import com.geeksville.mesh.ui.components.DeviceMetricsScreen
import com.geeksville.mesh.ui.components.EnvironmentMetricsScreen import com.geeksville.mesh.ui.components.EnvironmentMetricsScreen
import com.geeksville.mesh.ui.components.SignalMetricsScreen import com.geeksville.mesh.ui.components.SignalMetricsScreen
@ -242,20 +241,13 @@ fun NavGraph(
startDestination: String, startDestination: String,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
) { ) {
val connectionState by viewModel.connectionState.collectAsStateWithLifecycle() val state by viewModel.radioConfigState.collectAsStateWithLifecycle()
val connected = connectionState == ConnectionState.CONNECTED && node != null if (state.responseState.isWaiting()) {
val radioConfigState by viewModel.radioConfigState.collectAsStateWithLifecycle()
val isWaiting = radioConfigState.responseState.isWaiting()
if (isWaiting) {
PacketResponseStateDialog( PacketResponseStateDialog(
state = radioConfigState.responseState, state = state.responseState,
onDismiss = { onDismiss = viewModel::clearPacketResponse,
viewModel.clearPacketResponse()
},
onComplete = { onComplete = {
val route = radioConfigState.route val route = state.route
if (ConfigRoute.entries.any { it.name == route } || if (ConfigRoute.entries.any { it.name == route } ||
ModuleRoute.entries.any { it.name == route }) { ModuleRoute.entries.any { it.name == route }) {
navController.navigate(route = route) navController.navigate(route = route)
@ -294,14 +286,13 @@ fun NavGraph(
composable("RadioConfig") { composable("RadioConfig") {
RadioConfigScreen( RadioConfigScreen(
node = node, node = node,
enabled = connected && !isWaiting,
viewModel = viewModel, viewModel = viewModel,
) )
} }
composable(ConfigRoute.USER.name) { composable(ConfigRoute.USER.name) {
UserConfigItemList( UserConfigItemList(
userConfig = radioConfigState.userConfig, userConfig = state.userConfig,
enabled = connected, enabled = state.connected,
onSaveClicked = { userInput -> onSaveClicked = { userInput ->
viewModel.setOwner(userInput) viewModel.setOwner(userInput)
} }
@ -309,19 +300,19 @@ fun NavGraph(
} }
composable(ConfigRoute.CHANNELS.name) { composable(ConfigRoute.CHANNELS.name) {
ChannelSettingsItemList( ChannelSettingsItemList(
settingsList = radioConfigState.channelList, settingsList = state.channelList,
modemPresetName = Channel(loraConfig = radioConfigState.radioConfig.lora).name, modemPresetName = Channel(loraConfig = state.radioConfig.lora).name,
enabled = connected, enabled = state.connected,
maxChannels = viewModel.maxChannels, maxChannels = viewModel.maxChannels,
onPositiveClicked = { channelListInput -> onPositiveClicked = { channelListInput ->
viewModel.updateChannels(channelListInput, radioConfigState.channelList) viewModel.updateChannels(channelListInput, state.channelList)
}, },
) )
} }
composable(ConfigRoute.DEVICE.name) { composable(ConfigRoute.DEVICE.name) {
DeviceConfigItemList( DeviceConfigItemList(
deviceConfig = radioConfigState.radioConfig.device, deviceConfig = state.radioConfig.device,
enabled = connected, enabled = state.connected,
onSaveClicked = { deviceInput -> onSaveClicked = { deviceInput ->
val config = config { device = deviceInput } val config = config { device = deviceInput }
viewModel.setConfig(config) viewModel.setConfig(config)
@ -337,15 +328,15 @@ fun NavGraph(
) )
PositionConfigItemList( PositionConfigItemList(
location = currentPosition, location = currentPosition,
positionConfig = radioConfigState.radioConfig.position, positionConfig = state.radioConfig.position,
enabled = connected, enabled = state.connected,
onSaveClicked = { locationInput, positionInput -> onSaveClicked = { locationInput, positionInput ->
if (positionInput.fixedPosition) { if (positionInput.fixedPosition) {
if (locationInput != currentPosition) { if (locationInput != currentPosition) {
viewModel.setFixedPosition(locationInput) viewModel.setFixedPosition(locationInput)
} }
} else { } else {
if (radioConfigState.radioConfig.position.fixedPosition) { if (state.radioConfig.position.fixedPosition) {
// fixed position changed from enabled to disabled // fixed position changed from enabled to disabled
viewModel.removeFixedPosition() viewModel.removeFixedPosition()
} }
@ -357,8 +348,8 @@ fun NavGraph(
} }
composable(ConfigRoute.POWER.name) { composable(ConfigRoute.POWER.name) {
PowerConfigItemList( PowerConfigItemList(
powerConfig = radioConfigState.radioConfig.power, powerConfig = state.radioConfig.power,
enabled = connected, enabled = state.connected,
onSaveClicked = { powerInput -> onSaveClicked = { powerInput ->
val config = config { power = powerInput } val config = config { power = powerInput }
viewModel.setConfig(config) viewModel.setConfig(config)
@ -367,8 +358,8 @@ fun NavGraph(
} }
composable(ConfigRoute.NETWORK.name) { composable(ConfigRoute.NETWORK.name) {
NetworkConfigItemList( NetworkConfigItemList(
networkConfig = radioConfigState.radioConfig.network, networkConfig = state.radioConfig.network,
enabled = connected, enabled = state.connected,
onSaveClicked = { networkInput -> onSaveClicked = { networkInput ->
val config = config { network = networkInput } val config = config { network = networkInput }
viewModel.setConfig(config) viewModel.setConfig(config)
@ -377,8 +368,8 @@ fun NavGraph(
} }
composable(ConfigRoute.DISPLAY.name) { composable(ConfigRoute.DISPLAY.name) {
DisplayConfigItemList( DisplayConfigItemList(
displayConfig = radioConfigState.radioConfig.display, displayConfig = state.radioConfig.display,
enabled = connected, enabled = state.connected,
onSaveClicked = { displayInput -> onSaveClicked = { displayInput ->
val config = config { display = displayInput } val config = config { display = displayInput }
viewModel.setConfig(config) viewModel.setConfig(config)
@ -387,9 +378,9 @@ fun NavGraph(
} }
composable(ConfigRoute.LORA.name) { composable(ConfigRoute.LORA.name) {
LoRaConfigItemList( LoRaConfigItemList(
loraConfig = radioConfigState.radioConfig.lora, loraConfig = state.radioConfig.lora,
primarySettings = radioConfigState.channelList.getOrNull(0) ?: return@composable, primarySettings = state.channelList.getOrNull(0) ?: return@composable,
enabled = connected, enabled = state.connected,
onSaveClicked = { loraInput -> onSaveClicked = { loraInput ->
val config = config { lora = loraInput } val config = config { lora = loraInput }
viewModel.setConfig(config) viewModel.setConfig(config)
@ -399,8 +390,8 @@ fun NavGraph(
} }
composable(ConfigRoute.BLUETOOTH.name) { composable(ConfigRoute.BLUETOOTH.name) {
BluetoothConfigItemList( BluetoothConfigItemList(
bluetoothConfig = radioConfigState.radioConfig.bluetooth, bluetoothConfig = state.radioConfig.bluetooth,
enabled = connected, enabled = state.connected,
onSaveClicked = { bluetoothInput -> onSaveClicked = { bluetoothInput ->
val config = config { bluetooth = bluetoothInput } val config = config { bluetooth = bluetoothInput }
viewModel.setConfig(config) viewModel.setConfig(config)
@ -409,8 +400,8 @@ fun NavGraph(
} }
composable(ConfigRoute.SECURITY.name) { composable(ConfigRoute.SECURITY.name) {
SecurityConfigItemList( SecurityConfigItemList(
securityConfig = radioConfigState.radioConfig.security, securityConfig = state.radioConfig.security,
enabled = connected, enabled = state.connected,
onConfirm = { securityInput -> onConfirm = { securityInput ->
val config = config { security = securityInput } val config = config { security = securityInput }
viewModel.setConfig(config) viewModel.setConfig(config)
@ -419,8 +410,8 @@ fun NavGraph(
} }
composable(ModuleRoute.MQTT.name) { composable(ModuleRoute.MQTT.name) {
MQTTConfigItemList( MQTTConfigItemList(
mqttConfig = radioConfigState.moduleConfig.mqtt, mqttConfig = state.moduleConfig.mqtt,
enabled = connected, enabled = state.connected,
onSaveClicked = { mqttInput -> onSaveClicked = { mqttInput ->
val config = moduleConfig { mqtt = mqttInput } val config = moduleConfig { mqtt = mqttInput }
viewModel.setModuleConfig(config) viewModel.setModuleConfig(config)
@ -429,8 +420,8 @@ fun NavGraph(
} }
composable(ModuleRoute.SERIAL.name) { composable(ModuleRoute.SERIAL.name) {
SerialConfigItemList( SerialConfigItemList(
serialConfig = radioConfigState.moduleConfig.serial, serialConfig = state.moduleConfig.serial,
enabled = connected, enabled = state.connected,
onSaveClicked = { serialInput -> onSaveClicked = { serialInput ->
val config = moduleConfig { serial = serialInput } val config = moduleConfig { serial = serialInput }
viewModel.setModuleConfig(config) viewModel.setModuleConfig(config)
@ -439,14 +430,14 @@ fun NavGraph(
} }
composable(ModuleRoute.EXTERNAL_NOTIFICATION.name) { composable(ModuleRoute.EXTERNAL_NOTIFICATION.name) {
ExternalNotificationConfigItemList( ExternalNotificationConfigItemList(
ringtone = radioConfigState.ringtone, ringtone = state.ringtone,
extNotificationConfig = radioConfigState.moduleConfig.externalNotification, extNotificationConfig = state.moduleConfig.externalNotification,
enabled = connected, enabled = state.connected,
onSaveClicked = { ringtoneInput, extNotificationInput -> onSaveClicked = { ringtoneInput, extNotificationInput ->
if (ringtoneInput != radioConfigState.ringtone) { if (ringtoneInput != state.ringtone) {
viewModel.setRingtone(ringtoneInput) viewModel.setRingtone(ringtoneInput)
} }
if (extNotificationInput != radioConfigState.moduleConfig.externalNotification) { if (extNotificationInput != state.moduleConfig.externalNotification) {
val config = moduleConfig { externalNotification = extNotificationInput } val config = moduleConfig { externalNotification = extNotificationInput }
viewModel.setModuleConfig(config) viewModel.setModuleConfig(config)
} }
@ -455,8 +446,8 @@ fun NavGraph(
} }
composable(ModuleRoute.STORE_FORWARD.name) { composable(ModuleRoute.STORE_FORWARD.name) {
StoreForwardConfigItemList( StoreForwardConfigItemList(
storeForwardConfig = radioConfigState.moduleConfig.storeForward, storeForwardConfig = state.moduleConfig.storeForward,
enabled = connected, enabled = state.connected,
onSaveClicked = { storeForwardInput -> onSaveClicked = { storeForwardInput ->
val config = moduleConfig { storeForward = storeForwardInput } val config = moduleConfig { storeForward = storeForwardInput }
viewModel.setModuleConfig(config) viewModel.setModuleConfig(config)
@ -465,8 +456,8 @@ fun NavGraph(
} }
composable(ModuleRoute.RANGE_TEST.name) { composable(ModuleRoute.RANGE_TEST.name) {
RangeTestConfigItemList( RangeTestConfigItemList(
rangeTestConfig = radioConfigState.moduleConfig.rangeTest, rangeTestConfig = state.moduleConfig.rangeTest,
enabled = connected, enabled = state.connected,
onSaveClicked = { rangeTestInput -> onSaveClicked = { rangeTestInput ->
val config = moduleConfig { rangeTest = rangeTestInput } val config = moduleConfig { rangeTest = rangeTestInput }
viewModel.setModuleConfig(config) viewModel.setModuleConfig(config)
@ -475,8 +466,8 @@ fun NavGraph(
} }
composable(ModuleRoute.TELEMETRY.name) { composable(ModuleRoute.TELEMETRY.name) {
TelemetryConfigItemList( TelemetryConfigItemList(
telemetryConfig = radioConfigState.moduleConfig.telemetry, telemetryConfig = state.moduleConfig.telemetry,
enabled = connected, enabled = state.connected,
onSaveClicked = { telemetryInput -> onSaveClicked = { telemetryInput ->
val config = moduleConfig { telemetry = telemetryInput } val config = moduleConfig { telemetry = telemetryInput }
viewModel.setModuleConfig(config) viewModel.setModuleConfig(config)
@ -485,14 +476,14 @@ fun NavGraph(
} }
composable(ModuleRoute.CANNED_MESSAGE.name) { composable(ModuleRoute.CANNED_MESSAGE.name) {
CannedMessageConfigItemList( CannedMessageConfigItemList(
messages = radioConfigState.cannedMessageMessages, messages = state.cannedMessageMessages,
cannedMessageConfig = radioConfigState.moduleConfig.cannedMessage, cannedMessageConfig = state.moduleConfig.cannedMessage,
enabled = connected, enabled = state.connected,
onSaveClicked = { messagesInput, cannedMessageInput -> onSaveClicked = { messagesInput, cannedMessageInput ->
if (messagesInput != radioConfigState.cannedMessageMessages) { if (messagesInput != state.cannedMessageMessages) {
viewModel.setCannedMessages(messagesInput) viewModel.setCannedMessages(messagesInput)
} }
if (cannedMessageInput != radioConfigState.moduleConfig.cannedMessage) { if (cannedMessageInput != state.moduleConfig.cannedMessage) {
val config = moduleConfig { cannedMessage = cannedMessageInput } val config = moduleConfig { cannedMessage = cannedMessageInput }
viewModel.setModuleConfig(config) viewModel.setModuleConfig(config)
} }
@ -501,8 +492,8 @@ fun NavGraph(
} }
composable(ModuleRoute.AUDIO.name) { composable(ModuleRoute.AUDIO.name) {
AudioConfigItemList( AudioConfigItemList(
audioConfig = radioConfigState.moduleConfig.audio, audioConfig = state.moduleConfig.audio,
enabled = connected, enabled = state.connected,
onSaveClicked = { audioInput -> onSaveClicked = { audioInput ->
val config = moduleConfig { audio = audioInput } val config = moduleConfig { audio = audioInput }
viewModel.setModuleConfig(config) viewModel.setModuleConfig(config)
@ -511,8 +502,8 @@ fun NavGraph(
} }
composable(ModuleRoute.REMOTE_HARDWARE.name) { composable(ModuleRoute.REMOTE_HARDWARE.name) {
RemoteHardwareConfigItemList( RemoteHardwareConfigItemList(
remoteHardwareConfig = radioConfigState.moduleConfig.remoteHardware, remoteHardwareConfig = state.moduleConfig.remoteHardware,
enabled = connected, enabled = state.connected,
onSaveClicked = { remoteHardwareInput -> onSaveClicked = { remoteHardwareInput ->
val config = moduleConfig { remoteHardware = remoteHardwareInput } val config = moduleConfig { remoteHardware = remoteHardwareInput }
viewModel.setModuleConfig(config) viewModel.setModuleConfig(config)
@ -521,8 +512,8 @@ fun NavGraph(
} }
composable(ModuleRoute.NEIGHBOR_INFO.name) { composable(ModuleRoute.NEIGHBOR_INFO.name) {
NeighborInfoConfigItemList( NeighborInfoConfigItemList(
neighborInfoConfig = radioConfigState.moduleConfig.neighborInfo, neighborInfoConfig = state.moduleConfig.neighborInfo,
enabled = connected, enabled = state.connected,
onSaveClicked = { neighborInfoInput -> onSaveClicked = { neighborInfoInput ->
val config = moduleConfig { neighborInfo = neighborInfoInput } val config = moduleConfig { neighborInfo = neighborInfoInput }
viewModel.setModuleConfig(config) viewModel.setModuleConfig(config)
@ -531,8 +522,8 @@ fun NavGraph(
} }
composable(ModuleRoute.AMBIENT_LIGHTING.name) { composable(ModuleRoute.AMBIENT_LIGHTING.name) {
AmbientLightingConfigItemList( AmbientLightingConfigItemList(
ambientLightingConfig = radioConfigState.moduleConfig.ambientLighting, ambientLightingConfig = state.moduleConfig.ambientLighting,
enabled = connected, enabled = state.connected,
onSaveClicked = { ambientLightingInput -> onSaveClicked = { ambientLightingInput ->
val config = moduleConfig { ambientLighting = ambientLightingInput } val config = moduleConfig { ambientLighting = ambientLightingInput }
viewModel.setModuleConfig(config) viewModel.setModuleConfig(config)
@ -541,8 +532,8 @@ fun NavGraph(
} }
composable(ModuleRoute.DETECTION_SENSOR.name) { composable(ModuleRoute.DETECTION_SENSOR.name) {
DetectionSensorConfigItemList( DetectionSensorConfigItemList(
detectionSensorConfig = radioConfigState.moduleConfig.detectionSensor, detectionSensorConfig = state.moduleConfig.detectionSensor,
enabled = connected, enabled = state.connected,
onSaveClicked = { detectionSensorInput -> onSaveClicked = { detectionSensorInput ->
val config = moduleConfig { detectionSensor = detectionSensorInput } val config = moduleConfig { detectionSensor = detectionSensorInput }
viewModel.setModuleConfig(config) viewModel.setModuleConfig(config)
@ -551,8 +542,8 @@ fun NavGraph(
} }
composable(ModuleRoute.PAXCOUNTER.name) { composable(ModuleRoute.PAXCOUNTER.name) {
PaxcounterConfigItemList( PaxcounterConfigItemList(
paxcounterConfig = radioConfigState.moduleConfig.paxcounter, paxcounterConfig = state.moduleConfig.paxcounter,
enabled = connected, enabled = state.connected,
onSaveClicked = { paxcounterConfigInput -> onSaveClicked = { paxcounterConfigInput ->
val config = moduleConfig { paxcounter = paxcounterConfigInput } val config = moduleConfig { paxcounter = paxcounterConfigInput }
viewModel.setModuleConfig(config) viewModel.setModuleConfig(config)

Wyświetl plik

@ -44,6 +44,7 @@ import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.geeksville.mesh.ClientOnlyProtos.DeviceProfile import com.geeksville.mesh.ClientOnlyProtos.DeviceProfile
import com.geeksville.mesh.R import com.geeksville.mesh.R
import com.geeksville.mesh.database.entity.NodeEntity import com.geeksville.mesh.database.entity.NodeEntity
@ -55,11 +56,12 @@ import com.geeksville.mesh.ui.components.config.EditDeviceProfileDialog
@Composable @Composable
fun RadioConfigScreen( fun RadioConfigScreen(
node: NodeEntity?, node: NodeEntity?,
enabled: Boolean,
viewModel: RadioConfigViewModel, viewModel: RadioConfigViewModel,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
) { ) {
val isLocal = node?.num == viewModel.myNodeNum val isLocal = node?.num == viewModel.myNodeNum
val state by viewModel.radioConfigState.collectAsStateWithLifecycle()
val isWaiting = state.responseState.isWaiting()
var deviceProfile by remember { mutableStateOf<DeviceProfile?>(null) } var deviceProfile by remember { mutableStateOf<DeviceProfile?>(null) }
var showEditDeviceProfileDialog by remember { mutableStateOf(false) } var showEditDeviceProfileDialog by remember { mutableStateOf(false) }
@ -109,7 +111,7 @@ fun RadioConfigScreen(
} }
RadioConfigItemList( RadioConfigItemList(
enabled = enabled, enabled = state.connected && !isWaiting,
isLocal = isLocal, isLocal = isLocal,
modifier = modifier, modifier = modifier,
onRouteClick = { route -> onRouteClick = { route ->