Skip to content

Commit 1c37842

Browse files
authored
fix: Multiple bugs - settings text fields, dropdowns, missing override duty cycle, and MQTT icon display (#3833)
1 parent 9bc1b87 commit 1c37842

File tree

9 files changed

+58
-55
lines changed

9 files changed

+58
-55
lines changed

app/src/main/java/com/geeksville/mesh/service/MeshService.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -721,6 +721,7 @@ class MeshService : Service() {
721721
rssi = packet.rxRssi,
722722
replyId = data.replyId,
723723
relayNode = packet.relayNode,
724+
viaMqtt = packet.viaMqtt,
724725
)
725726
}
726727

core/database/src/main/kotlin/org/meshtastic/core/database/entity/Packet.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ data class PacketEntity(
5252
packetId = packetId,
5353
emojis = reactions.toReaction(getNode),
5454
replyId = data.replyId,
55-
viaMqtt = node.viaMqtt,
55+
viaMqtt = data.viaMqtt,
5656
relayNode = data.relayNode,
5757
relays = data.relays,
5858
)

core/model/src/main/kotlin/org/meshtastic/core/model/DataPacket.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ data class DataPacket(
6363
var replyId: Int? = null, // If this is a reply to a previous message, this is the ID of that message
6464
var relayNode: Int? = null,
6565
var relays: Int = 0,
66+
var viaMqtt: Boolean = false, // True if this packet passed via MQTT somewhere along its path
6667
) : Parcelable {
6768

6869
/** If there was an error with this message, this string describes what was wrong. */

core/ui/src/main/kotlin/org/meshtastic/core/ui/component/EditTextPreference.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ fun EditTextPreference(
163163
onValueChanged: (Double) -> Unit,
164164
modifier: Modifier = Modifier,
165165
summary: String? = null,
166+
onFocusChanged: (FocusState) -> Unit = {},
166167
) {
167168
var valueState by remember(value) { mutableStateOf(value.toString()) }
168169
val decimalSeparators = setOf('.', ',', '٫', '', '·') // set of possible decimal separators
@@ -185,7 +186,7 @@ fun EditTextPreference(
185186
}
186187
}
187188
},
188-
onFocusChanged = {},
189+
onFocusChanged = onFocusChanged,
189190
modifier = modifier,
190191
)
191192
}

feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/CannedMessageConfigItemList.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ fun CannedMessageConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(),
7272
enabled = state.connected,
7373
responseState = state.responseState,
7474
onDismissPacketResponse = viewModel::clearPacketResponse,
75+
additionalDirtyCheck = { messagesInput != messages },
76+
onDiscard = { messagesInput = messages },
7577
onSave = {
7678
if (messagesInput != messages) {
7779
viewModel.setCannedMessages(messagesInput)

feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/ExternalNotificationConfigItemList.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ fun ExternalNotificationConfigScreen(
130130
enabled = state.connected,
131131
responseState = state.responseState,
132132
onDismissPacketResponse = viewModel::clearPacketResponse,
133+
additionalDirtyCheck = { ringtoneInput != ringtone },
134+
onDiscard = { ringtoneInput = ringtone },
133135
onSave = {
134136
if (ringtoneInput != ringtone) {
135137
viewModel.setRingtone(ringtoneInput)
@@ -259,7 +261,7 @@ fun ExternalNotificationConfigScreen(
259261
DropDownPreference(
260262
title = stringResource(Res.string.output_duration_milliseconds),
261263
items = outputItems.map { it.value to it.toDisplayString() },
262-
selectedItem = formState.value.outputMs,
264+
selectedItem = formState.value.outputMs.toLong(),
263265
enabled = state.connected,
264266
onItemSelected = { formState.value = formState.value.copy { outputMs = it.toInt() } },
265267
)
@@ -268,7 +270,7 @@ fun ExternalNotificationConfigScreen(
268270
DropDownPreference(
269271
title = stringResource(Res.string.nag_timeout_seconds),
270272
items = nagItems.map { it.value to it.toDisplayString() },
271-
selectedItem = formState.value.nagTimeout,
273+
selectedItem = formState.value.nagTimeout.toLong(),
272274
enabled = state.connected,
273275
onItemSelected = { formState.value = formState.value.copy { nagTimeout = it.toInt() } },
274276
)

feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/LoRaConfigItemList.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ import org.meshtastic.core.strings.lora
4747
import org.meshtastic.core.strings.modem_preset
4848
import org.meshtastic.core.strings.ok_to_mqtt
4949
import org.meshtastic.core.strings.options
50+
import org.meshtastic.core.strings.override_duty_cycle
5051
import org.meshtastic.core.strings.override_frequency_mhz
5152
import org.meshtastic.core.strings.pa_fan_disabled
5253
import org.meshtastic.core.strings.region_frequency_plan
@@ -169,6 +170,14 @@ fun LoRaConfigScreen(viewModel: RadioConfigViewModel, onBack: () -> Unit) {
169170
containerColor = CardDefaults.cardColors().containerColor,
170171
)
171172
HorizontalDivider()
173+
SwitchPreference(
174+
title = stringResource(Res.string.override_duty_cycle),
175+
checked = formState.value.overrideDutyCycle,
176+
enabled = state.connected,
177+
onCheckedChange = { formState.value = formState.value.copy { overrideDutyCycle = it } },
178+
containerColor = CardDefaults.cardColors().containerColor,
179+
)
180+
HorizontalDivider()
172181
val hopLimitItems = remember { hopLimits }
173182
DropDownPreference(
174183
title = stringResource(Res.string.hop_limit),

feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/PositionConfigItemList.kt

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,8 @@ fun PositionConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBa
149149
enabled = state.connected,
150150
responseState = state.responseState,
151151
onDismissPacketResponse = viewModel::clearPacketResponse,
152+
additionalDirtyCheck = { locationInput != currentPosition },
153+
onDiscard = { locationInput = currentPosition },
152154
onSave = {
153155
if (formState.value.fixedPosition) {
154156
if (locationInput != currentPosition) {
@@ -233,9 +235,9 @@ fun PositionConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBa
233235
value = locationInput.latitude,
234236
enabled = state.connected,
235237
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }),
236-
onValueChanged = { value ->
237-
if (value >= -90 && value <= 90.0) {
238-
locationInput = locationInput.copy(latitude = value)
238+
onValueChanged = { lat: Double ->
239+
if (lat >= -90 && lat <= 90.0) {
240+
locationInput = locationInput.copy(latitude = lat)
239241
}
240242
},
241243
)
@@ -245,9 +247,9 @@ fun PositionConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBa
245247
value = locationInput.longitude,
246248
enabled = state.connected,
247249
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }),
248-
onValueChanged = { value ->
249-
if (value >= -180 && value <= 180.0) {
250-
locationInput = locationInput.copy(longitude = value)
250+
onValueChanged = { lon: Double ->
251+
if (lon >= -180 && lon <= 180.0) {
252+
locationInput = locationInput.copy(longitude = lon)
251253
}
252254
},
253255
)
@@ -257,7 +259,7 @@ fun PositionConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBa
257259
value = locationInput.altitude,
258260
enabled = state.connected,
259261
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }),
260-
onValueChanged = { value -> locationInput = locationInput.copy(altitude = value) },
262+
onValueChanged = { alt: Int -> locationInput = locationInput.copy(altitude = alt) },
261263
)
262264
HorizontalDivider()
263265
TextButton(

feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/RadioConfigScreenList.kt

Lines changed: 29 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -22,20 +22,14 @@ import androidx.compose.animation.expandIn
2222
import androidx.compose.animation.fadeIn
2323
import androidx.compose.animation.fadeOut
2424
import androidx.compose.animation.shrinkOut
25-
import androidx.compose.animation.slideInVertically
26-
import androidx.compose.animation.slideOutVertically
2725
import androidx.compose.foundation.layout.Arrangement
28-
import androidx.compose.foundation.layout.Box
2926
import androidx.compose.foundation.layout.PaddingValues
30-
import androidx.compose.foundation.layout.Spacer
3127
import androidx.compose.foundation.layout.fillMaxSize
32-
import androidx.compose.foundation.layout.height
3328
import androidx.compose.foundation.layout.padding
3429
import androidx.compose.foundation.lazy.LazyColumn
3530
import androidx.compose.foundation.lazy.LazyListScope
3631
import androidx.compose.material3.Scaffold
3732
import androidx.compose.runtime.Composable
38-
import androidx.compose.ui.Alignment
3933
import androidx.compose.ui.Modifier
4034
import androidx.compose.ui.platform.LocalFocusManager
4135
import androidx.compose.ui.unit.dp
@@ -59,6 +53,8 @@ fun <T : MessageLite> RadioConfigScreenList(
5953
enabled: Boolean,
6054
onSave: (T) -> Unit,
6155
modifier: Modifier = Modifier,
56+
additionalDirtyCheck: () -> Boolean = { false },
57+
onDiscard: () -> Unit = {},
6258
content: LazyListScope.() -> Unit,
6359
) {
6460
val focusManager = LocalFocusManager.current
@@ -81,48 +77,37 @@ fun <T : MessageLite> RadioConfigScreenList(
8177
)
8278
},
8379
) { innerPadding ->
84-
val showFooterButtons = configState.isDirty
80+
val showFooterButtons = configState.isDirty || additionalDirtyCheck()
8581

86-
Box(modifier = Modifier.padding(innerPadding)) {
87-
LazyColumn(
88-
modifier = Modifier.fillMaxSize(),
89-
contentPadding = PaddingValues(16.dp),
90-
verticalArrangement = Arrangement.spacedBy(16.dp),
91-
) {
92-
content()
82+
LazyColumn(
83+
modifier = Modifier.padding(innerPadding).fillMaxSize(),
84+
contentPadding = PaddingValues(16.dp),
85+
verticalArrangement = Arrangement.spacedBy(16.dp),
86+
) {
87+
content()
9388

94-
item {
95-
AnimatedVisibility(
96-
visible = showFooterButtons,
97-
modifier = Modifier.align(Alignment.BottomCenter),
98-
enter = expandIn(),
99-
exit = shrinkOut(),
100-
) {
101-
Spacer(modifier = Modifier.height(64.dp))
102-
}
89+
item {
90+
AnimatedVisibility(
91+
visible = showFooterButtons,
92+
enter = fadeIn() + expandIn(),
93+
exit = fadeOut() + shrinkOut(),
94+
) {
95+
PreferenceFooter(
96+
enabled = enabled && showFooterButtons,
97+
negativeText = stringResource(Res.string.discard_changes),
98+
onNegativeClicked = {
99+
focusManager.clearFocus()
100+
configState.reset()
101+
onDiscard()
102+
},
103+
positiveText = stringResource(Res.string.save_changes),
104+
onPositiveClicked = {
105+
focusManager.clearFocus()
106+
onSave(configState.value)
107+
},
108+
)
103109
}
104110
}
105-
106-
AnimatedVisibility(
107-
visible = showFooterButtons,
108-
modifier = Modifier.align(Alignment.BottomCenter),
109-
enter = fadeIn() + slideInVertically(initialOffsetY = { it }),
110-
exit = fadeOut() + slideOutVertically(targetOffsetY = { it }),
111-
) {
112-
PreferenceFooter(
113-
enabled = enabled && configState.isDirty,
114-
negativeText = stringResource(Res.string.discard_changes),
115-
onNegativeClicked = {
116-
focusManager.clearFocus()
117-
configState.reset()
118-
},
119-
positiveText = stringResource(Res.string.save_changes),
120-
onPositiveClicked = {
121-
focusManager.clearFocus()
122-
onSave(configState.value)
123-
},
124-
)
125-
}
126111
}
127112
}
128113
}

0 commit comments

Comments
 (0)