diff --git a/android/app/src/main/java/com/bfalls/suntimealerts/alarm/presentation/ui/HomeScreen.kt b/android/app/src/main/java/com/bfalls/suntimealerts/alarm/presentation/ui/HomeScreen.kt index 7b87adc..89783f5 100644 --- a/android/app/src/main/java/com/bfalls/suntimealerts/alarm/presentation/ui/HomeScreen.kt +++ b/android/app/src/main/java/com/bfalls/suntimealerts/alarm/presentation/ui/HomeScreen.kt @@ -33,6 +33,7 @@ import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.imePadding +import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items //import androidx.compose.foundation.lazy.stickyHeader @@ -99,7 +100,6 @@ import androidx.compose.ui.semantics.SemanticsPropertyKey import androidx.compose.ui.semantics.SemanticsPropertyReceiver import androidx.compose.ui.semantics.semantics import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.IntOffset import androidx.compose.ui.unit.IntSize @@ -363,34 +363,31 @@ private fun AlarmRow( onToggle: (Boolean) -> Unit, onEdit: () -> Unit ) { - Box( + Row( modifier = Modifier .fillMaxWidth() .clickable { onEdit() } - .padding(vertical = 8.dp) + .padding(vertical = 8.dp), + verticalAlignment = Alignment.CenterVertically ) { - Column(modifier = Modifier.align(Alignment.CenterStart)) { + Column(modifier = Modifier.weight(1f)) { Text( text = formatOffset(alarm.offsetMinutes), fontWeight = FontWeight.Bold ) - if (alarm.label.isNotBlank()) { - Text( - text = alarm.label, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - } - } - Row( - modifier = Modifier.align(Alignment.CenterEnd), - verticalAlignment = Alignment.CenterVertically - ) { - Switch( - checked = alarm.enabled, - onCheckedChange = onToggle + val description = appendRecurrenceLabel( + label = alarm.label, + recurrenceSummary = recurrenceSummary(alarm.recurrenceDays) ) + if (description.isNotBlank()) { + Text(text = description) + } } + Spacer(modifier = Modifier.width(12.dp)) + Switch( + checked = alarm.enabled, + onCheckedChange = onToggle + ) } } @@ -600,6 +597,7 @@ private fun AlarmEditorSheet( onValueChange = { label = it }, label = { Text("Label") }, modifier = Modifier.fillMaxWidth(), + maxLines = 3, colors = TextFieldDefaults.colors( focusedContainerColor = MaterialTheme.colorScheme.surfaceColorAtElevation(4.dp), unfocusedContainerColor = MaterialTheme.colorScheme.surfaceColorAtElevation(2.dp), diff --git a/android/app/src/main/java/com/bfalls/suntimealerts/alarm/presentation/ui/RecurrenceSummary.kt b/android/app/src/main/java/com/bfalls/suntimealerts/alarm/presentation/ui/RecurrenceSummary.kt new file mode 100644 index 0000000..568880a --- /dev/null +++ b/android/app/src/main/java/com/bfalls/suntimealerts/alarm/presentation/ui/RecurrenceSummary.kt @@ -0,0 +1,65 @@ +package com.bfalls.suntimealerts.alarm.presentation.ui + +import com.bfalls.suntimealerts.alarm.domain.model.includesDay +import java.time.DayOfWeek + +private val orderedDays = listOf( + DayOfWeek.SUNDAY, + DayOfWeek.MONDAY, + DayOfWeek.TUESDAY, + DayOfWeek.WEDNESDAY, + DayOfWeek.THURSDAY, + DayOfWeek.FRIDAY, + DayOfWeek.SATURDAY +) + +private val weekdaySet = setOf( + DayOfWeek.MONDAY, + DayOfWeek.TUESDAY, + DayOfWeek.WEDNESDAY, + DayOfWeek.THURSDAY, + DayOfWeek.FRIDAY +) + +private val weekendSet = setOf(DayOfWeek.SATURDAY, DayOfWeek.SUNDAY) + +fun recurrenceSummary(recurrenceMask: Int?): String? { + if (recurrenceMask == null) return null + + val days = orderedDays.filter { recurrenceMask.includesDay(it) } + if (days.isEmpty()) return null + + val daySet = days.toSet() + + return when { + days.size == orderedDays.size -> "every day" + daySet == weekdaySet -> "every weekday" + daySet == weekendSet -> "every weekend" + else -> formatDayList(days) + } +} + +fun appendRecurrenceLabel(label: String, recurrenceSummary: String?): String { + if (recurrenceSummary.isNullOrBlank()) return label + if (label.isBlank()) return recurrenceSummary + return "$label, $recurrenceSummary" +} + +private fun formatDayList(days: List): String { + val names = days.map(::shortName) + return when (names.size) { + 1 -> names.first() + 2 -> "${names[0]} and ${names[1]}" + else -> names.dropLast(1).joinToString(separator = ", ") + ", and ${names.last()}" + } +} + +private fun shortName(dayOfWeek: DayOfWeek): String = when (dayOfWeek) { + DayOfWeek.SUNDAY -> "Sun" + DayOfWeek.MONDAY -> "Mon" + DayOfWeek.TUESDAY -> "Tue" + DayOfWeek.WEDNESDAY -> "Wed" + DayOfWeek.THURSDAY -> "Thu" + DayOfWeek.FRIDAY -> "Fri" + DayOfWeek.SATURDAY -> "Sat" +}