mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-04-20 22:23:37 +00:00
feat(mqtt): migrate to MQTTastic-Client-KMP (#5165)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: jamesarich <2199651+jamesarich@users.noreply.github.com>
This commit is contained in:
parent
b828a1271c
commit
305a487dd7
12 changed files with 271 additions and 131 deletions
|
|
@ -43,6 +43,7 @@ import org.meshtastic.core.domain.usecase.settings.RadioResponseResult
|
|||
import org.meshtastic.core.domain.usecase.settings.ToggleAnalyticsUseCase
|
||||
import org.meshtastic.core.domain.usecase.settings.ToggleHomoglyphEncodingUseCase
|
||||
import org.meshtastic.core.model.ConnectionState
|
||||
import org.meshtastic.core.model.MqttConnectionState
|
||||
import org.meshtastic.core.model.MyNodeInfo
|
||||
import org.meshtastic.core.model.Node
|
||||
import org.meshtastic.core.model.Position
|
||||
|
|
@ -52,6 +53,7 @@ import org.meshtastic.core.repository.HomoglyphPrefs
|
|||
import org.meshtastic.core.repository.LocationRepository
|
||||
import org.meshtastic.core.repository.LocationService
|
||||
import org.meshtastic.core.repository.MapConsentPrefs
|
||||
import org.meshtastic.core.repository.MqttManager
|
||||
import org.meshtastic.core.repository.NodeRepository
|
||||
import org.meshtastic.core.repository.PacketRepository
|
||||
import org.meshtastic.core.repository.RadioConfigRepository
|
||||
|
|
@ -125,6 +127,7 @@ open class RadioConfigViewModel(
|
|||
private val processRadioResponseUseCase: ProcessRadioResponseUseCase,
|
||||
private val locationService: LocationService,
|
||||
private val fileService: FileService,
|
||||
private val mqttManager: MqttManager,
|
||||
) : ViewModel() {
|
||||
val analyticsAllowedFlow = analyticsPrefs.analyticsAllowed
|
||||
|
||||
|
|
@ -138,6 +141,9 @@ open class RadioConfigViewModel(
|
|||
toggleHomoglyphEncodingUseCase()
|
||||
}
|
||||
|
||||
/** MQTT proxy connection state for the settings UI. */
|
||||
val mqttConnectionState: StateFlow<MqttConnectionState> = mqttManager.mqttConnectionState
|
||||
|
||||
private val destNumFlow = MutableStateFlow(savedStateHandle.get<Int>("destNum"))
|
||||
|
||||
fun initDestNum(id: Int?) {
|
||||
|
|
|
|||
|
|
@ -18,17 +18,32 @@
|
|||
|
||||
package org.meshtastic.feature.settings.radio.component
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.text.KeyboardActions
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.material3.CardDefaults
|
||||
import androidx.compose.material3.HorizontalDivider
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalFocusManager
|
||||
import androidx.compose.ui.text.input.ImeAction
|
||||
import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
import org.meshtastic.core.model.MqttConnectionState
|
||||
import org.meshtastic.core.resources.Res
|
||||
import org.meshtastic.core.resources.address
|
||||
import org.meshtastic.core.resources.default_mqtt_address
|
||||
|
|
@ -38,6 +53,11 @@ import org.meshtastic.core.resources.map_reporting
|
|||
import org.meshtastic.core.resources.mqtt
|
||||
import org.meshtastic.core.resources.mqtt_config
|
||||
import org.meshtastic.core.resources.mqtt_enabled
|
||||
import org.meshtastic.core.resources.mqtt_status_connected
|
||||
import org.meshtastic.core.resources.mqtt_status_connecting
|
||||
import org.meshtastic.core.resources.mqtt_status_disconnected
|
||||
import org.meshtastic.core.resources.mqtt_status_inactive
|
||||
import org.meshtastic.core.resources.mqtt_status_reconnecting
|
||||
import org.meshtastic.core.resources.password
|
||||
import org.meshtastic.core.resources.proxy_to_client_enabled
|
||||
import org.meshtastic.core.resources.root_topic
|
||||
|
|
@ -54,6 +74,7 @@ import org.meshtastic.proto.ModuleConfig
|
|||
fun MQTTConfigScreen(viewModel: RadioConfigViewModel, onBack: () -> Unit) {
|
||||
val state by viewModel.radioConfigState.collectAsStateWithLifecycle()
|
||||
val destNode by viewModel.destNode.collectAsStateWithLifecycle()
|
||||
val mqttProxyState by viewModel.mqttConnectionState.collectAsStateWithLifecycle()
|
||||
val destNum = destNode?.num
|
||||
val mqttConfig = state.moduleConfig.mqtt ?: ModuleConfig.MQTTConfig()
|
||||
val formState = rememberConfigState(initialValue = mqttConfig)
|
||||
|
|
@ -86,6 +107,8 @@ fun MQTTConfigScreen(viewModel: RadioConfigViewModel, onBack: () -> Unit) {
|
|||
viewModel.setModuleConfig(config)
|
||||
},
|
||||
) {
|
||||
item { MqttStatusRow(mqttProxyState) }
|
||||
|
||||
item {
|
||||
TitledCard(title = stringResource(Res.string.mqtt_config)) {
|
||||
SwitchPreference(
|
||||
|
|
@ -210,3 +233,32 @@ fun MQTTConfigScreen(viewModel: RadioConfigViewModel, onBack: () -> Unit) {
|
|||
}
|
||||
|
||||
private const val MIN_INTERVAL_SECS = 3600
|
||||
|
||||
private val AmberColor = Color(0xFFFFA000)
|
||||
private val GreenColor = Color(0xFF4CAF50)
|
||||
|
||||
@Composable
|
||||
private fun MqttStatusRow(state: MqttConnectionState) {
|
||||
val (label, color) =
|
||||
when (state) {
|
||||
MqttConnectionState.INACTIVE ->
|
||||
stringResource(Res.string.mqtt_status_inactive) to MaterialTheme.colorScheme.outline
|
||||
MqttConnectionState.DISCONNECTED ->
|
||||
stringResource(Res.string.mqtt_status_disconnected) to MaterialTheme.colorScheme.error
|
||||
MqttConnectionState.CONNECTING -> stringResource(Res.string.mqtt_status_connecting) to AmberColor
|
||||
MqttConnectionState.CONNECTED -> stringResource(Res.string.mqtt_status_connected) to GreenColor
|
||||
MqttConnectionState.RECONNECTING -> stringResource(Res.string.mqtt_status_reconnecting) to AmberColor
|
||||
}
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||
modifier = Modifier.padding(horizontal = 4.dp),
|
||||
) {
|
||||
Box(modifier = Modifier.size(10.dp).clip(CircleShape).background(color))
|
||||
Text(
|
||||
text = label,
|
||||
style = MaterialTheme.typography.labelLarge,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ import org.meshtastic.core.repository.HomoglyphPrefs
|
|||
import org.meshtastic.core.repository.LocationRepository
|
||||
import org.meshtastic.core.repository.LocationService
|
||||
import org.meshtastic.core.repository.MapConsentPrefs
|
||||
import org.meshtastic.core.repository.MqttManager
|
||||
import org.meshtastic.core.repository.PacketRepository
|
||||
import org.meshtastic.core.repository.RadioConfigRepository
|
||||
import org.meshtastic.core.repository.ServiceRepository
|
||||
|
|
@ -99,6 +100,7 @@ class RadioConfigViewModelTest {
|
|||
private val processRadioResponseUseCase: ProcessRadioResponseUseCase = mock(MockMode.autofill)
|
||||
private val locationService: LocationService = mock(MockMode.autofill)
|
||||
private val fileService: FileService = mock(MockMode.autofill)
|
||||
private val mqttManager: MqttManager = mock(MockMode.autofill)
|
||||
private val uiPrefs: UiPrefs = mock(MockMode.autofill)
|
||||
|
||||
private lateinit var viewModel: RadioConfigViewModel
|
||||
|
|
@ -121,6 +123,9 @@ class RadioConfigViewModelTest {
|
|||
every { serviceRepository.connectionState } returns
|
||||
MutableStateFlow(org.meshtastic.core.model.ConnectionState.Connected)
|
||||
|
||||
every { mqttManager.mqttConnectionState } returns
|
||||
MutableStateFlow(org.meshtastic.core.model.MqttConnectionState.INACTIVE)
|
||||
|
||||
every { uiPrefs.showQuickChat } returns MutableStateFlow(false)
|
||||
|
||||
viewModel = createViewModel()
|
||||
|
|
@ -152,6 +157,7 @@ class RadioConfigViewModelTest {
|
|||
processRadioResponseUseCase = processRadioResponseUseCase,
|
||||
locationService = locationService,
|
||||
fileService = fileService,
|
||||
mqttManager = mqttManager,
|
||||
)
|
||||
|
||||
@Test
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue