fix(edit): recurrence picker review fixes + picker unification (#42) #89

Merged
makiolaj merged 6 commits from feat/recurrence-exdate into release/v2.16.0 2026-07-20 13:29:16 +00:00
Showing only changes of commit ccd433fee1 - Show all commits

View File

@@ -1382,8 +1382,43 @@ private fun RecurrencePickerDialog(
)
} else {
Column(
verticalArrangement = Arrangement.spacedBy(8.dp),
modifier = Modifier.padding(horizontal = 24.dp),
modifier = Modifier.fillMaxWidth(),
verticalArrangement = Arrangement.spacedBy(16.dp),
) {
// A live, human-readable read-out of the rule being built, so the
// effect of the controls below is never a guess.
Text(
text = recurrenceText(
SimpleRecurrence(
freq = freq,
interval = interval ?: 1,
end = customEnd ?: RecurrenceEnd.Never,
byDays = if (freq == RecurrenceFreq.Weekly) {
daysMask.toDaySet()
} else {
emptySet()
},
).toRRule(),
locale,
),
style = MaterialTheme.typography.titleMedium,
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp),
)
// How often: an interval amount plus a frequency segmented row —
// all four units on show, no unit hidden behind a dropdown.
Surface(
color = MaterialTheme.colorScheme.surfaceContainerHigh,
shape = groupedShape(Position.Alone),
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp),
) {
Column(
modifier = Modifier.padding(16.dp),
verticalArrangement = Arrangement.spacedBy(16.dp),
) {
Row(verticalAlignment = Alignment.CenterVertically) {
Text(
@@ -1396,31 +1431,52 @@ private fun RecurrencePickerDialog(
onValueChange = { intervalText = it },
placeholder = "1",
)
Spacer(Modifier.width(12.dp))
DialogUnitDropdown(
label = stringResource(recurrenceUnitLabel(freq)),
entries = RecurrenceFreq.entries.map {
stringResource(recurrenceUnitLabel(it))
},
onPick = { freq = RecurrenceFreq.entries[it] },
}
SingleChoiceSegmentedButtonRow(modifier = Modifier.fillMaxWidth()) {
RecurrenceFreq.entries.forEachIndexed { index, entry ->
SegmentedButton(
selected = freq == entry,
onClick = { freq = entry },
shape = SegmentedButtonDefaults.itemShape(
index, RecurrenceFreq.entries.size,
),
label = { Text(stringResource(recurrenceUnitLabel(entry))) },
)
}
if (freq == RecurrenceFreq.Weekly) {
}
}
}
// Weekday picks — only meaningful on a weekly rule.
AnimatedVisibility(visible = freq == RecurrenceFreq.Weekly) {
Surface(
color = MaterialTheme.colorScheme.surfaceContainerHigh,
shape = groupedShape(Position.Alone),
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp),
) {
WeekdayToggleRow(
selected = daysMask.toDaySet(),
onToggle = { day -> daysMask = daysMask xor day.toMaskBit() },
locale = locale,
modifier = Modifier.padding(16.dp),
)
}
}
// Ends: a connected never / on-a-date / after-N group, the count
// field folding into the bottom of the run when chosen.
Column {
Text(
text = stringResource(R.string.event_edit_recurrence_ends),
style = MaterialTheme.typography.bodyMedium,
style = MaterialTheme.typography.labelLarge,
color = MaterialTheme.colorScheme.onSurfaceVariant,
modifier = Modifier.padding(start = 16.dp, bottom = 8.dp),
)
}
GroupedRow(
title = stringResource(R.string.event_edit_recurrence_end_never),
position = positionOf(0, 3),
position = Position.Top,
selected = endMode == RecurrenceEndMode.Never,
onClick = { endMode = RecurrenceEndMode.Never },
)
@@ -1432,7 +1488,7 @@ private fun RecurrencePickerDialog(
.withLocale(locale).format(it.toJavaLocalDate())
}
},
position = positionOf(1, 3),
position = Position.Middle,
selected = endMode == RecurrenceEndMode.Until,
onClick = {
endMode = RecurrenceEndMode.Until
@@ -1441,14 +1497,25 @@ private fun RecurrencePickerDialog(
)
GroupedRow(
title = stringResource(R.string.event_edit_recurrence_end_count),
position = positionOf(2, 3),
position = if (endMode == RecurrenceEndMode.Count) {
Position.Middle
} else {
Position.Bottom
},
selected = endMode == RecurrenceEndMode.Count,
onClick = { endMode = RecurrenceEndMode.Count },
)
if (endMode == RecurrenceEndMode.Count) {
Surface(
color = MaterialTheme.colorScheme.surfaceContainerHigh,
shape = groupedShape(Position.Bottom),
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp),
) {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.padding(horizontal = 24.dp, vertical = 4.dp),
modifier = Modifier.padding(16.dp),
) {
DialogAmountField(
value = countText,
@@ -1464,6 +1531,9 @@ private fun RecurrencePickerDialog(
}
}
}
}
}
}
if (showUntilPicker) {
CalendarDatePickerDialog(
@@ -1489,6 +1559,7 @@ private fun WeekdayToggleRow(
selected: Set<DayOfWeek>,
onToggle: (DayOfWeek) -> Unit,
locale: Locale,
modifier: Modifier = Modifier,
) {
val days = remember(locale) {
val first = WeekFields.of(locale).firstDayOfWeek.toKotlinDayOfWeek()
@@ -1496,7 +1567,7 @@ private fun WeekdayToggleRow(
}
Row(
horizontalArrangement = Arrangement.SpaceBetween,
modifier = Modifier.fillMaxWidth(),
modifier = modifier.fillMaxWidth(),
) {
days.forEach { day ->
val isSelected = day in selected