Skip to content

Commit 192dd8d

Browse files
eriedclaude
andcommitted
italic hints, segmented comparator, guard alarm save, trim strings, v0.1.1
- Italic HintText style; trim trailing periods from hint/caption/help copy - Scan screen: shorter labels, drop powered-on hint - Metric detail: drop "Historical" prefix and waiting-for-data block - Alarm editor: two-way segmented comparator; disable Save when no output - Flic screen: remove "No buttons paired" label - Voice defaults: Time third in order, enabled for Trigger; PWM off by default - Bump versionName to 0.1.1 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 6d3a050 commit 192dd8d

12 files changed

Lines changed: 126 additions & 167 deletions

File tree

app/build.gradle.kts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ android {
1818
applicationId = "com.eried.eucplanet"
1919
minSdk = 29
2020
targetSdk = 35
21-
versionCode = 1
22-
versionName = "0.1.0"
21+
versionCode = 2
22+
versionName = "0.1.1"
2323

2424
val buildStamp = SimpleDateFormat("yyMMdd.HHmm")
2525
.apply { timeZone = TimeZone.getTimeZone("UTC") }

app/src/main/java/com/eried/eucplanet/data/model/AppSettings.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,16 +43,16 @@ data class AppSettings(
4343
val triggerReportSpeed: Boolean = true,
4444
val triggerReportBattery: Boolean = true,
4545
val triggerReportTemp: Boolean = true,
46-
val triggerReportPwm: Boolean = true,
46+
val triggerReportPwm: Boolean = false,
4747
val triggerReportDistance: Boolean = true,
48-
val triggerReportTime: Boolean = false,
48+
val triggerReportTime: Boolean = true,
4949

5050
// Voice report: include recording state
5151
val voiceReportRecording: Boolean = false,
5252
val triggerReportRecording: Boolean = true,
5353

54-
// Voice report item order (comma-separated: Speed,Battery,Temp,PWM,Distance,Recording,Time)
55-
val voiceReportOrder: String = "Speed,Battery,Temp,PWM,Distance,Recording,Time",
54+
// Voice report item order (comma-separated: Speed,Battery,Time,Temp,PWM,Distance,Recording)
55+
val voiceReportOrder: String = "Speed,Battery,Time,Temp,PWM,Distance,Recording",
5656

5757
// Special announcements (event-driven)
5858
val announceWheelLock: Boolean = true,

app/src/main/java/com/eried/eucplanet/ui/common/InfoHint.kt

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import androidx.compose.material3.Text
1212
import androidx.compose.runtime.Composable
1313
import androidx.compose.ui.Alignment
1414
import androidx.compose.ui.Modifier
15+
import androidx.compose.ui.text.font.FontStyle
16+
import androidx.compose.ui.text.style.TextAlign
1517
import androidx.compose.ui.unit.dp
1618

1719
@Composable
@@ -33,7 +35,25 @@ fun InfoHint(
3335
Text(
3436
text,
3537
style = MaterialTheme.typography.bodyMedium,
36-
color = MaterialTheme.colorScheme.onSurfaceVariant
38+
color = MaterialTheme.colorScheme.onSurfaceVariant,
39+
fontStyle = FontStyle.Italic
3740
)
3841
}
3942
}
43+
44+
@Composable
45+
fun HintText(
46+
text: String,
47+
modifier: Modifier = Modifier,
48+
small: Boolean = false,
49+
textAlign: TextAlign? = null
50+
) {
51+
Text(
52+
text,
53+
modifier = modifier,
54+
style = if (small) MaterialTheme.typography.bodySmall else MaterialTheme.typography.bodyMedium,
55+
color = MaterialTheme.colorScheme.onSurfaceVariant,
56+
fontStyle = FontStyle.Italic,
57+
textAlign = textAlign
58+
)
59+
}

app/src/main/java/com/eried/eucplanet/ui/dashboard/MetricDetailScreen.kt

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -186,12 +186,7 @@ fun MetricDetailScreen(
186186
.height(280.dp)
187187
)
188188
} else {
189-
// No data yet — show empty placeholder graph
190189
Spacer(Modifier.height(16.dp))
191-
Text(stringResource(R.string.metric_waiting),
192-
style = MaterialTheme.typography.bodyMedium,
193-
color = MaterialTheme.colorScheme.onSurfaceVariant)
194-
Spacer(Modifier.height(12.dp))
195190
EmptyGraph(
196191
color = metricType.color,
197192
modifier = Modifier

app/src/main/java/com/eried/eucplanet/ui/recording/RecordingScreen.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ import androidx.compose.ui.unit.sp
6868
import androidx.hilt.navigation.compose.hiltViewModel
6969
import com.eried.eucplanet.R
7070
import com.eried.eucplanet.data.model.TripRecord
71+
import com.eried.eucplanet.ui.common.HintText
7172
import com.eried.eucplanet.ui.common.InfoHint
7273
import com.eried.eucplanet.ui.theme.AccentGreen
7374
import com.eried.eucplanet.ui.theme.AccentRed
@@ -311,10 +312,9 @@ fun RecordingScreen(
311312
}
312313

313314
if (!recording && !importing && trips.isEmpty()) {
314-
Text(
315+
HintText(
315316
stringResource(R.string.recording_auto_record_tip),
316-
style = MaterialTheme.typography.bodySmall,
317-
color = MaterialTheme.colorScheme.onSurfaceVariant,
317+
small = true,
318318
modifier = Modifier.padding(vertical = 8.dp)
319319
)
320320
}

app/src/main/java/com/eried/eucplanet/ui/recording/TripDetailScreen.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ import androidx.compose.ui.viewinterop.AndroidView
6161
import androidx.hilt.navigation.compose.hiltViewModel
6262
import com.eried.eucplanet.R
6363
import com.eried.eucplanet.data.model.TripRecord
64+
import com.eried.eucplanet.ui.common.HintText
6465
import com.eried.eucplanet.ui.theme.AccentBlue
6566
import com.eried.eucplanet.ui.theme.AccentGreen
6667
import com.eried.eucplanet.ui.theme.AccentOrange
@@ -113,8 +114,7 @@ fun TripDetailScreen(
113114
horizontalAlignment = Alignment.CenterHorizontally,
114115
verticalArrangement = Arrangement.Center
115116
) {
116-
Text(stringResource(R.string.recording_no_data),
117-
color = MaterialTheme.colorScheme.onSurfaceVariant)
117+
HintText(stringResource(R.string.recording_no_data))
118118
}
119119
} else {
120120
Column(

app/src/main/java/com/eried/eucplanet/ui/scan/ScanScreen.kt

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -179,14 +179,6 @@ fun ScanScreen(
179179

180180
Spacer(Modifier.height(16.dp))
181181

182-
if (devices.isEmpty() && isScanning) {
183-
Text(
184-
stringResource(R.string.scan_hint),
185-
style = MaterialTheme.typography.bodyMedium,
186-
color = MaterialTheme.colorScheme.onSurfaceVariant
187-
)
188-
}
189-
190182
LazyColumn(verticalArrangement = Arrangement.spacedBy(8.dp)) {
191183
items(devices) { device ->
192184
Card(

app/src/main/java/com/eried/eucplanet/ui/settings/AlarmSettingsContent.kt

Lines changed: 49 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ import androidx.compose.material3.IconButton
3333
import androidx.compose.material3.MaterialTheme
3434
import androidx.compose.material3.MenuAnchorType
3535
import androidx.compose.material3.OutlinedTextField
36+
import androidx.compose.material3.SegmentedButton
37+
import androidx.compose.material3.SegmentedButtonDefaults
38+
import androidx.compose.material3.SingleChoiceSegmentedButtonRow
3639
import androidx.compose.material3.Slider
3740
import androidx.compose.material3.Switch
3841
import androidx.compose.material3.Text
@@ -57,6 +60,7 @@ import com.eried.eucplanet.R
5760
import com.eried.eucplanet.data.model.AlarmComparator
5861
import com.eried.eucplanet.data.model.AlarmMetric
5962
import com.eried.eucplanet.data.model.AlarmRule
63+
import com.eried.eucplanet.ui.common.HintText
6064
import com.eried.eucplanet.ui.common.InfoHint
6165
import com.eried.eucplanet.ui.theme.AccentBlue
6266
import com.eried.eucplanet.ui.theme.AccentGreen
@@ -104,11 +108,7 @@ fun AlarmSettingsContent(
104108
) {
105109
Spacer(Modifier.height(8.dp))
106110

107-
Text(
108-
stringResource(R.string.alarm_help),
109-
style = MaterialTheme.typography.bodySmall,
110-
color = MaterialTheme.colorScheme.onSurfaceVariant
111-
)
111+
HintText(stringResource(R.string.alarm_help), small = true)
112112

113113
Spacer(Modifier.height(12.dp))
114114

@@ -370,15 +370,26 @@ private fun AlarmRuleEditorDialog(
370370

371371
Spacer(Modifier.height(6.dp))
372372

373-
// Comparator dropdown
373+
// Comparator: 2-way segmented selector
374374
val selectedComp = AlarmComparator.parse(comparator)
375-
val comparatorOptions = AlarmComparator.entries.map { it.name to "${it.symbol} ${stringResource(it.labelRes)}" }
376-
DropdownSelect(
377-
label = stringResource(R.string.alarm_comparator_label),
378-
selected = stringResource(selectedComp.labelRes),
379-
options = comparatorOptions,
380-
onSelect = { comparator = it }
375+
Text(
376+
stringResource(R.string.alarm_comparator_label),
377+
fontSize = 12.sp,
378+
color = MaterialTheme.colorScheme.onSurfaceVariant
381379
)
380+
Spacer(Modifier.height(4.dp))
381+
val comparatorEntries = AlarmComparator.entries
382+
SingleChoiceSegmentedButtonRow(modifier = Modifier.fillMaxWidth()) {
383+
comparatorEntries.forEachIndexed { index, entry ->
384+
SegmentedButton(
385+
selected = entry == selectedComp,
386+
onClick = { comparator = entry.name },
387+
shape = SegmentedButtonDefaults.itemShape(index, comparatorEntries.size)
388+
) {
389+
Text("${entry.symbol} ${stringResource(entry.labelRes)}")
390+
}
391+
}
392+
}
382393

383394
Spacer(Modifier.height(6.dp))
384395

@@ -465,11 +476,7 @@ private fun AlarmRuleEditorDialog(
465476
modifier = Modifier.fillMaxWidth(),
466477
minLines = 2
467478
)
468-
Text(
469-
stringResource(R.string.alarm_voice_template_help),
470-
fontSize = 10.sp,
471-
color = MaterialTheme.colorScheme.onSurfaceVariant
472-
)
479+
HintText(stringResource(R.string.alarm_voice_template_help), small = true)
473480
}
474481

475482
Spacer(Modifier.height(8.dp))
@@ -513,11 +520,7 @@ private fun AlarmRuleEditorDialog(
513520
valueRange = 3f..60f,
514521
steps = 56
515522
)
516-
Text(
517-
stringResource(R.string.alarm_cooldown_help),
518-
fontSize = 10.sp,
519-
color = MaterialTheme.colorScheme.onSurfaceVariant
520-
)
523+
HintText(stringResource(R.string.alarm_cooldown_help), small = true)
521524

522525
Row(
523526
modifier = Modifier.fillMaxWidth(),
@@ -527,11 +530,7 @@ private fun AlarmRuleEditorDialog(
527530
Text(stringResource(R.string.alarm_repeat), fontSize = 13.sp)
528531
Switch(checked = repeatWhileActive, onCheckedChange = { repeatWhileActive = it })
529532
}
530-
Text(
531-
stringResource(R.string.alarm_repeat_help),
532-
fontSize = 10.sp,
533-
color = MaterialTheme.colorScheme.onSurfaceVariant
534-
)
533+
HintText(stringResource(R.string.alarm_repeat_help), small = true)
535534
Spacer(Modifier.height(6.dp))
536535
val example = if (repeatWhileActive) {
537536
stringResource(R.string.alarm_repeat_on_example_fmt, cooldownSeconds)
@@ -553,26 +552,30 @@ private fun AlarmRuleEditorDialog(
553552
) {
554553
TextButton(onClick = onDismiss) { Text(stringResource(R.string.action_cancel)) }
555554
Spacer(Modifier.width(8.dp))
556-
Button(onClick = {
557-
onSave(
558-
(rule ?: AlarmRule()).copy(
559-
name = name,
560-
metric = metric,
561-
comparator = comparator,
562-
threshold = threshold,
563-
beepEnabled = beepEnabled,
564-
beepFrequency = beepFrequency,
565-
beepDurationMs = beepDurationMs,
566-
beepCount = beepCount,
567-
voiceEnabled = voiceEnabled,
568-
voiceText = voiceText,
569-
vibrateEnabled = vibrateEnabled,
570-
vibrateDurationMs = vibrateDurationMs,
571-
cooldownSeconds = cooldownSeconds,
572-
repeatWhileActive = repeatWhileActive
555+
val hasOutput = beepEnabled || voiceEnabled || vibrateEnabled
556+
Button(
557+
enabled = hasOutput,
558+
onClick = {
559+
onSave(
560+
(rule ?: AlarmRule()).copy(
561+
name = name,
562+
metric = metric,
563+
comparator = comparator,
564+
threshold = threshold,
565+
beepEnabled = beepEnabled,
566+
beepFrequency = beepFrequency,
567+
beepDurationMs = beepDurationMs,
568+
beepCount = beepCount,
569+
voiceEnabled = voiceEnabled,
570+
voiceText = voiceText,
571+
vibrateEnabled = vibrateEnabled,
572+
vibrateDurationMs = vibrateDurationMs,
573+
cooldownSeconds = cooldownSeconds,
574+
repeatWhileActive = repeatWhileActive
575+
)
573576
)
574-
)
575-
}) {
577+
}
578+
) {
576579
Text(stringResource(R.string.action_save))
577580
}
578581
}

app/src/main/java/com/eried/eucplanet/ui/settings/AutomationsContent.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ import androidx.hilt.navigation.compose.hiltViewModel
4848
import com.eried.eucplanet.R
4949
import com.eried.eucplanet.service.encodeVolumeCurve
5050
import com.eried.eucplanet.service.parseVolumeCurve
51+
import com.eried.eucplanet.ui.common.HintText
5152
import com.eried.eucplanet.ui.theme.AccentBlue
5253
import com.eried.eucplanet.ui.theme.AccentGreen
5354
import com.eried.eucplanet.ui.theme.AccentOrange
@@ -167,9 +168,7 @@ fun AutomationsContent(
167168
)
168169
}
169170
} else {
170-
Text(stringResource(R.string.auto_waiting_gps),
171-
style = MaterialTheme.typography.bodySmall,
172-
color = MaterialTheme.colorScheme.onSurfaceVariant)
171+
HintText(stringResource(R.string.auto_waiting_gps), small = true)
173172
}
174173
}
175174

app/src/main/java/com/eried/eucplanet/ui/settings/FlicScreen.kt

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ import androidx.compose.ui.unit.dp
5252
import androidx.hilt.navigation.compose.hiltViewModel
5353
import com.eried.eucplanet.R
5454
import com.eried.eucplanet.data.model.FlicAction
55+
import com.eried.eucplanet.ui.common.HintText
5556
import com.eried.eucplanet.ui.theme.AccentBlue
5657
import com.eried.eucplanet.ui.theme.AccentRed
5758

@@ -63,7 +64,6 @@ fun FlicScreen(
6364
) {
6465
val settings by viewModel.settings.collectAsState()
6566
val scanning by viewModel.scanning.collectAsState()
66-
val pairedButtons by viewModel.pairedButtons.collectAsState()
6767
var forgetTarget by remember { mutableStateOf<Pair<String, String>?>(null) }
6868

6969
forgetTarget?.let { (addr, name) ->
@@ -115,11 +115,7 @@ fun FlicScreen(
115115
modifier = Modifier.padding(16.dp),
116116
horizontalAlignment = Alignment.CenterHorizontally
117117
) {
118-
Text(
119-
stringResource(R.string.flic_scan_hint),
120-
style = MaterialTheme.typography.bodyMedium,
121-
color = MaterialTheme.colorScheme.onSurfaceVariant
122-
)
118+
HintText(stringResource(R.string.flic_scan_hint))
123119
Spacer(Modifier.height(12.dp))
124120
if (scanning) {
125121
CircularProgressIndicator(modifier = Modifier.padding(8.dp))
@@ -138,15 +134,6 @@ fun FlicScreen(
138134
}
139135
}
140136

141-
// Paired buttons
142-
if (pairedButtons.isEmpty()) {
143-
Text(
144-
stringResource(R.string.flic_no_buttons),
145-
style = MaterialTheme.typography.bodyLarge,
146-
color = MaterialTheme.colorScheme.onSurfaceVariant
147-
)
148-
}
149-
150137
// Button 1 config
151138
settings.flic1Address?.let { addr ->
152139
ButtonConfig(

0 commit comments

Comments
 (0)