From 983886e8f176f8fdd61744f1a2772d1c9be71c23 Mon Sep 17 00:00:00 2001 From: claude Date: Sat, 25 Jul 2026 11:13:10 +0200 Subject: [PATCH] =?UTF-8?q?Avsluta-dialogen:=20varaktighet=20och=20sluttid?= =?UTF-8?q?=20som=20pickers=20ist=C3=A4llet=20f=C3=B6r=20steppers?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ±-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 Claude-Session: https://claude.ai/code/session_01Kf4MAbZ3c3B4Xy5XfuGsCP --- .../fitnessdroid/ui/session/SessionScreen.kt | 123 +++++++++++++----- 1 file changed, 94 insertions(+), 29 deletions(-) diff --git a/app/src/main/java/eu/brassepc/fitnessdroid/ui/session/SessionScreen.kt b/app/src/main/java/eu/brassepc/fitnessdroid/ui/session/SessionScreen.kt index 5772c2d..bca5a15 100644 --- a/app/src/main/java/eu/brassepc/fitnessdroid/ui/session/SessionScreen.kt +++ b/app/src/main/java/eu/brassepc/fitnessdroid/ui/session/SessionScreen.kt @@ -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) {