Avsluta-dialogen: varaktighet och sluttid som pickers istället för steppers
Some checks failed
release / build-release (push) Has been cancelled

±-knapparna fick inte plats på smala skärmar (Oukitel WP9) och var
klyddiga. Nu: två breda knappar — Varaktighet ('hur länge gymmade du?')
och Slut (klockslag, rullar över till nästa dag om det är före starten).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kf4MAbZ3c3B4Xy5XfuGsCP
This commit is contained in:
2026-07-25 11:13:10 +02:00
parent 8928a4edb4
commit 983886e8f1

View File

@@ -475,6 +475,63 @@ private fun CompleteSessionDialog(
var showCalorieInfo by remember { mutableStateOf(false) }
var showDatePicker by remember { mutableStateOf(false) }
var showTimePicker by remember { mutableStateOf(false) }
var showDurationPicker by remember { mutableStateOf(false) }
var showEndPicker by remember { mutableStateOf(false) }
if (showDurationPicker) {
val durationState = androidx.compose.material3.rememberTimePickerState(
initialHour = (durationSeconds / 3600).coerceAtMost(23),
initialMinute = (durationSeconds % 3600) / 60,
is24Hour = true,
)
AlertDialog(
onDismissRequest = { showDurationPicker = false },
title = { Text("Hur länge gymmade du?") },
text = { androidx.compose.material3.TimePicker(state = durationState) },
confirmButton = {
TextButton(onClick = {
durationSeconds = (durationState.hour * 3600 + durationState.minute * 60)
.coerceAtLeast(60)
showDurationPicker = false
}) { Text("OK") }
},
dismissButton = {
TextButton(onClick = { showDurationPicker = false }) { Text("Avbryt") }
},
)
}
if (showEndPicker) {
val zone = java.time.ZoneId.systemDefault()
val end = java.time.Instant.ofEpochMilli(startEpochMs + durationSeconds * 1000L).atZone(zone)
val endState = androidx.compose.material3.rememberTimePickerState(
initialHour = end.hour,
initialMinute = end.minute,
is24Hour = true,
)
AlertDialog(
onDismissRequest = { showEndPicker = false },
title = { Text("När slutade du?") },
text = { androidx.compose.material3.TimePicker(state = endState) },
confirmButton = {
TextButton(onClick = {
val start = java.time.Instant.ofEpochMilli(startEpochMs).atZone(zone)
var newEnd = start.toLocalDate()
.atTime(endState.hour, endState.minute).atZone(zone)
// Sluttid före starten? Då menas nästa dag.
if (!newEnd.toInstant().isAfter(start.toInstant())) {
newEnd = newEnd.plusDays(1)
}
durationSeconds = ((newEnd.toInstant().toEpochMilli() - startEpochMs) / 1000)
.toInt().coerceAtLeast(60)
showEndPicker = false
}) { Text("OK") }
},
dismissButton = {
TextButton(onClick = { showEndPicker = false }) { Text("Avbryt") }
},
)
}
if (showDatePicker) {
val dateState = androidx.compose.material3.rememberDatePickerState(
@@ -597,39 +654,47 @@ private fun CompleteSessionDialog(
}
}
Column(verticalArrangement = Arrangement.spacedBy(4.dp)) {
Text(
"VARAKTIGHET",
style = MaterialTheme.typography.labelSmall,
color = MaterialTheme.colorScheme.onSurfaceVariant,
)
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(6.dp),
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
val zone = java.time.ZoneId.systemDefault()
val startDay = java.time.Instant.ofEpochMilli(startEpochMs)
.atZone(zone).toLocalDate()
val end = java.time.Instant.ofEpochMilli(startEpochMs + durationSeconds * 1000L)
.atZone(zone)
Column(
modifier = Modifier.weight(1f),
verticalArrangement = Arrangement.spacedBy(4.dp),
) {
FilledTonalButton(onClick = {
durationSeconds = (durationSeconds - 300).coerceAtLeast(60)
}) { Text("5 m") }
FilledTonalButton(onClick = {
durationSeconds = (durationSeconds - 60).coerceAtLeast(60)
}) { Text("1 m") }
Text(
"%d:%02d".format(durationSeconds / 3600, (durationSeconds % 3600) / 60),
style = MaterialTheme.typography.headlineSmall,
fontWeight = FontWeight.Bold,
textAlign = TextAlign.Center,
modifier = Modifier.weight(1f),
"VARAKTIGHET",
style = MaterialTheme.typography.labelSmall,
color = MaterialTheme.colorScheme.onSurfaceVariant,
)
FilledTonalButton(onClick = { durationSeconds += 60 }) { Text("+1 m") }
FilledTonalButton(onClick = { durationSeconds += 300 }) { Text("+5 m") }
FilledTonalButton(
onClick = { showDurationPicker = true },
modifier = Modifier.fillMaxWidth(),
) {
Text("%d:%02d".format(durationSeconds / 3600, (durationSeconds % 3600) / 60))
}
}
Column(
modifier = Modifier.weight(1f),
verticalArrangement = Arrangement.spacedBy(4.dp),
) {
Text(
"SLUT",
style = MaterialTheme.typography.labelSmall,
color = MaterialTheme.colorScheme.onSurfaceVariant,
)
FilledTonalButton(
onClick = { showEndPicker = true },
modifier = Modifier.fillMaxWidth(),
) {
Text(
"%02d:%02d".format(end.hour, end.minute) +
if (end.toLocalDate() != startDay) " +1d" else ""
)
}
}
Text(
"Slut: " + java.time.Instant.ofEpochMilli(startEpochMs + durationSeconds * 1000L)
.atZone(java.time.ZoneId.systemDefault())
.format(java.time.format.DateTimeFormatter.ofPattern("EEE d MMM HH:mm")),
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.onSurfaceVariant,
)
}
Row(verticalAlignment = Alignment.CenterVertically) {