feat: full-screen selection pickers (retire OptionCard modals, bar actions)
Unify the app's "choose one" surfaces on the full-screen picker style (floret-kit FullScreenPicker/OptionPicker) instead of the OptionCard modal dialogs, for consistency across the app: - Event editor: visibility + add-field -> OptionPicker; reminder, recurrence rule, and colour -> FullScreenPicker, with the custom-value Add / OK and the colour Reset carried in the app-bar via the picker's new `actions` slot; the save-conflict chooser -> full-screen. - The recurring scope choosers stay compact OptionCard popups — saving an edit to, or deleting, a recurring event — since a quick 2-3 option decision reads better as a popup than a near-empty full screen. Bumps the floret-kit pin (55ad536 -> e1919ca) for the FullScreenPicker `actions` passthrough. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -134,6 +134,7 @@ import de.jeanlucmakiola.floret.components.GroupedRow
|
|||||||
import de.jeanlucmakiola.calendula.ui.common.MILLIS_PER_DAY
|
import de.jeanlucmakiola.calendula.ui.common.MILLIS_PER_DAY
|
||||||
import de.jeanlucmakiola.floret.components.InlineTextField
|
import de.jeanlucmakiola.floret.components.InlineTextField
|
||||||
import de.jeanlucmakiola.floret.components.OptionCard
|
import de.jeanlucmakiola.floret.components.OptionCard
|
||||||
|
import de.jeanlucmakiola.floret.components.OptionPicker
|
||||||
import de.jeanlucmakiola.floret.components.Position
|
import de.jeanlucmakiola.floret.components.Position
|
||||||
import de.jeanlucmakiola.floret.components.positionOf
|
import de.jeanlucmakiola.floret.components.positionOf
|
||||||
import de.jeanlucmakiola.calendula.ui.common.REMINDER_PRESETS
|
import de.jeanlucmakiola.calendula.ui.common.REMINDER_PRESETS
|
||||||
@@ -345,29 +346,29 @@ private fun SaveConflictDialog(
|
|||||||
onDiscard: () -> Unit,
|
onDiscard: () -> Unit,
|
||||||
onDismiss: () -> Unit,
|
onDismiss: () -> Unit,
|
||||||
) {
|
) {
|
||||||
AlertDialog(
|
FullScreenPicker(
|
||||||
onDismissRequest = onDismiss,
|
title = stringResource(R.string.event_edit_conflict_title),
|
||||||
title = { Text(stringResource(R.string.event_edit_conflict_title)) },
|
onDismiss = onDismiss,
|
||||||
text = {
|
) {
|
||||||
Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
|
Text(
|
||||||
Text(stringResource(R.string.event_edit_conflict_body))
|
text = stringResource(R.string.event_edit_conflict_body),
|
||||||
Spacer(Modifier.height(4.dp))
|
style = MaterialTheme.typography.bodyMedium,
|
||||||
OptionCard(
|
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||||
label = stringResource(R.string.event_edit_conflict_overwrite),
|
modifier = Modifier.padding(horizontal = 24.dp, vertical = 8.dp),
|
||||||
supportingText = stringResource(R.string.event_edit_conflict_overwrite_hint),
|
)
|
||||||
onClick = onOverwrite,
|
GroupedRow(
|
||||||
)
|
title = stringResource(R.string.event_edit_conflict_overwrite),
|
||||||
OptionCard(
|
summary = stringResource(R.string.event_edit_conflict_overwrite_hint),
|
||||||
label = stringResource(R.string.event_edit_conflict_discard),
|
position = positionOf(0, 2),
|
||||||
supportingText = stringResource(R.string.event_edit_conflict_discard_hint),
|
onClick = onOverwrite,
|
||||||
onClick = onDiscard,
|
)
|
||||||
)
|
GroupedRow(
|
||||||
}
|
title = stringResource(R.string.event_edit_conflict_discard),
|
||||||
},
|
summary = stringResource(R.string.event_edit_conflict_discard_hint),
|
||||||
confirmButton = {
|
position = positionOf(1, 2),
|
||||||
TextButton(onClick = onDismiss) { Text(stringResource(R.string.dialog_cancel)) }
|
onClick = onDiscard,
|
||||||
},
|
)
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1064,24 +1065,19 @@ private fun FieldPickerDialog(
|
|||||||
onSelect: (EventFormField) -> Unit,
|
onSelect: (EventFormField) -> Unit,
|
||||||
onDismiss: () -> Unit,
|
onDismiss: () -> Unit,
|
||||||
) {
|
) {
|
||||||
AlertDialog(
|
FullScreenPicker(
|
||||||
onDismissRequest = onDismiss,
|
title = stringResource(R.string.event_edit_more_fields),
|
||||||
title = { Text(stringResource(R.string.event_edit_more_fields)) },
|
onDismiss = onDismiss,
|
||||||
text = {
|
) {
|
||||||
Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
|
hiddenFields.forEachIndexed { index, field ->
|
||||||
hiddenFields.forEach { field ->
|
GroupedRow(
|
||||||
OptionCard(
|
title = stringResource(eventFormFieldLabel(field)),
|
||||||
label = stringResource(eventFormFieldLabel(field)),
|
position = positionOf(index, hiddenFields.size),
|
||||||
onClick = { onSelect(field) },
|
leading = { Icon(imageVector = eventFormFieldIcon(field), contentDescription = null) },
|
||||||
icon = eventFormFieldIcon(field),
|
onClick = { onSelect(field) },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
confirmButton = {
|
|
||||||
TextButton(onClick = onDismiss) { Text(stringResource(R.string.dialog_cancel)) }
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Quick-pick lead times offered as chips in the reminder dialog. */
|
/** Quick-pick lead times offered as chips in the reminder dialog. */
|
||||||
@@ -1106,41 +1102,10 @@ private fun ReminderPickerDialog(
|
|||||||
?.takeIf { it in 1..999 }
|
?.takeIf { it in 1..999 }
|
||||||
?.let { it * unit.minutesFactor }
|
?.let { it * unit.minutesFactor }
|
||||||
|
|
||||||
AlertDialog(
|
FullScreenPicker(
|
||||||
onDismissRequest = onDismiss,
|
title = stringResource(R.string.event_edit_add_reminder),
|
||||||
title = { Text(stringResource(R.string.event_edit_add_reminder)) },
|
onDismiss = onDismiss,
|
||||||
text = {
|
actions = {
|
||||||
if (!customMode) {
|
|
||||||
Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
|
|
||||||
REMINDER_QUICK_PICKS.filterNot { it in alreadyChosen }.forEach { minutes ->
|
|
||||||
OptionCard(
|
|
||||||
label = reminderLabel(minutes),
|
|
||||||
onClick = { onSelect(minutes) },
|
|
||||||
)
|
|
||||||
}
|
|
||||||
OptionCard(
|
|
||||||
label = stringResource(R.string.event_edit_reminder_custom),
|
|
||||||
onClick = { customMode = true },
|
|
||||||
labelColor = MaterialTheme.colorScheme.primary,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
|
||||||
DialogAmountField(
|
|
||||||
value = amountText,
|
|
||||||
onValueChange = { amountText = it },
|
|
||||||
placeholder = "10",
|
|
||||||
)
|
|
||||||
Spacer(Modifier.width(12.dp))
|
|
||||||
DialogUnitDropdown(
|
|
||||||
label = stringResource(reminderUnitLabel(unit)),
|
|
||||||
entries = ReminderUnit.entries.map { stringResource(reminderUnitLabel(it)) },
|
|
||||||
onPick = { unit = ReminderUnit.entries[it] },
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
confirmButton = {
|
|
||||||
// The quick-pick list adds on tap; only the custom step needs Add.
|
// The quick-pick list adds on tap; only the custom step needs Add.
|
||||||
if (customMode) {
|
if (customMode) {
|
||||||
TextButton(
|
TextButton(
|
||||||
@@ -1149,10 +1114,41 @@ private fun ReminderPickerDialog(
|
|||||||
) { Text(stringResource(R.string.event_edit_add)) }
|
) { Text(stringResource(R.string.event_edit_add)) }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
dismissButton = {
|
) {
|
||||||
TextButton(onClick = onDismiss) { Text(stringResource(R.string.dialog_cancel)) }
|
if (!customMode) {
|
||||||
},
|
val presets = REMINDER_QUICK_PICKS.filterNot { it in alreadyChosen }
|
||||||
)
|
val rowCount = presets.size + 1
|
||||||
|
presets.forEachIndexed { index, minutes ->
|
||||||
|
GroupedRow(
|
||||||
|
title = reminderLabel(minutes),
|
||||||
|
position = positionOf(index, rowCount),
|
||||||
|
onClick = { onSelect(minutes) },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
GroupedRow(
|
||||||
|
title = stringResource(R.string.event_edit_reminder_custom),
|
||||||
|
position = positionOf(rowCount - 1, rowCount),
|
||||||
|
onClick = { customMode = true },
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = Modifier.padding(horizontal = 24.dp, vertical = 8.dp),
|
||||||
|
) {
|
||||||
|
DialogAmountField(
|
||||||
|
value = amountText,
|
||||||
|
onValueChange = { amountText = it },
|
||||||
|
placeholder = "10",
|
||||||
|
)
|
||||||
|
Spacer(Modifier.width(12.dp))
|
||||||
|
DialogUnitDropdown(
|
||||||
|
label = stringResource(reminderUnitLabel(unit)),
|
||||||
|
entries = ReminderUnit.entries.map { stringResource(reminderUnitLabel(it)) },
|
||||||
|
onPick = { unit = ReminderUnit.entries[it] },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** How a custom recurrence ends; mirrors [RecurrenceEnd] in saveable form. */
|
/** How a custom recurrence ends; mirrors [RecurrenceEnd] in saveable form. */
|
||||||
@@ -1222,109 +1218,10 @@ private fun RecurrencePickerDialog(
|
|||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
AlertDialog(
|
FullScreenPicker(
|
||||||
onDismissRequest = onDismiss,
|
title = stringResource(R.string.event_detail_recurrence),
|
||||||
title = { Text(stringResource(R.string.event_detail_recurrence)) },
|
onDismiss = onDismiss,
|
||||||
text = {
|
actions = {
|
||||||
if (!customMode) {
|
|
||||||
Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
|
|
||||||
OptionCard(
|
|
||||||
label = stringResource(R.string.event_edit_recurrence_none),
|
|
||||||
onClick = { onSelect(null) },
|
|
||||||
selected = current == null,
|
|
||||||
)
|
|
||||||
RecurrenceFreq.entries.forEach { entry ->
|
|
||||||
OptionCard(
|
|
||||||
label = stringResource(recurrencePresetLabel(entry)),
|
|
||||||
onClick = { onSelect(SimpleRecurrence(entry).toRRule()) },
|
|
||||||
selected = isPlainPreset && parsed?.freq == entry,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
OptionCard(
|
|
||||||
label = stringResource(R.string.event_edit_recurrence_custom),
|
|
||||||
onClick = { customMode = true },
|
|
||||||
selected = current != null && !isPlainPreset,
|
|
||||||
labelColor = MaterialTheme.colorScheme.primary,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
|
|
||||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
|
||||||
Text(
|
|
||||||
text = stringResource(R.string.event_edit_recurrence_every),
|
|
||||||
style = MaterialTheme.typography.titleMedium,
|
|
||||||
)
|
|
||||||
Spacer(Modifier.width(12.dp))
|
|
||||||
DialogAmountField(
|
|
||||||
value = intervalText,
|
|
||||||
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] },
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if (freq == RecurrenceFreq.Weekly) {
|
|
||||||
Spacer(Modifier.height(4.dp))
|
|
||||||
WeekdayToggleRow(
|
|
||||||
selected = daysMask.toDaySet(),
|
|
||||||
onToggle = { day -> daysMask = daysMask xor day.toMaskBit() },
|
|
||||||
locale = locale,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
Spacer(Modifier.height(4.dp))
|
|
||||||
Text(
|
|
||||||
text = stringResource(R.string.event_edit_recurrence_ends),
|
|
||||||
style = MaterialTheme.typography.bodyMedium,
|
|
||||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
|
||||||
)
|
|
||||||
OptionCard(
|
|
||||||
label = stringResource(R.string.event_edit_recurrence_end_never),
|
|
||||||
onClick = { endMode = RecurrenceEndMode.Never },
|
|
||||||
selected = endMode == RecurrenceEndMode.Never,
|
|
||||||
)
|
|
||||||
OptionCard(
|
|
||||||
label = stringResource(R.string.event_edit_recurrence_end_until),
|
|
||||||
onClick = {
|
|
||||||
endMode = RecurrenceEndMode.Until
|
|
||||||
showUntilPicker = true
|
|
||||||
},
|
|
||||||
supportingText = untilDate?.let {
|
|
||||||
remember(it, locale) {
|
|
||||||
DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM)
|
|
||||||
.withLocale(locale).format(it.toJavaLocalDate())
|
|
||||||
}
|
|
||||||
},
|
|
||||||
selected = endMode == RecurrenceEndMode.Until,
|
|
||||||
)
|
|
||||||
OptionCard(
|
|
||||||
label = stringResource(R.string.event_edit_recurrence_end_count),
|
|
||||||
onClick = { endMode = RecurrenceEndMode.Count },
|
|
||||||
selected = endMode == RecurrenceEndMode.Count,
|
|
||||||
)
|
|
||||||
if (endMode == RecurrenceEndMode.Count) {
|
|
||||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
|
||||||
DialogAmountField(
|
|
||||||
value = countText,
|
|
||||||
onValueChange = { countText = it },
|
|
||||||
placeholder = "10",
|
|
||||||
)
|
|
||||||
Spacer(Modifier.width(12.dp))
|
|
||||||
Text(
|
|
||||||
text = stringResource(R.string.event_edit_recurrence_times),
|
|
||||||
style = MaterialTheme.typography.titleMedium,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
confirmButton = {
|
|
||||||
// The preset list applies on tap; only the custom step needs OK.
|
// The preset list applies on tap; only the custom step needs OK.
|
||||||
if (customMode) {
|
if (customMode) {
|
||||||
TextButton(
|
TextButton(
|
||||||
@@ -1333,10 +1230,113 @@ private fun RecurrencePickerDialog(
|
|||||||
) { Text(stringResource(R.string.dialog_ok)) }
|
) { Text(stringResource(R.string.dialog_ok)) }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
dismissButton = {
|
) {
|
||||||
TextButton(onClick = onDismiss) { Text(stringResource(R.string.dialog_cancel)) }
|
if (!customMode) {
|
||||||
},
|
val rowCount = RecurrenceFreq.entries.size + 2
|
||||||
)
|
GroupedRow(
|
||||||
|
title = stringResource(R.string.event_edit_recurrence_none),
|
||||||
|
position = positionOf(0, rowCount),
|
||||||
|
selected = current == null,
|
||||||
|
onClick = { onSelect(null) },
|
||||||
|
)
|
||||||
|
RecurrenceFreq.entries.forEachIndexed { index, entry ->
|
||||||
|
GroupedRow(
|
||||||
|
title = stringResource(recurrencePresetLabel(entry)),
|
||||||
|
position = positionOf(index + 1, rowCount),
|
||||||
|
selected = isPlainPreset && parsed?.freq == entry,
|
||||||
|
onClick = { onSelect(SimpleRecurrence(entry).toRRule()) },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
GroupedRow(
|
||||||
|
title = stringResource(R.string.event_edit_recurrence_custom),
|
||||||
|
position = positionOf(rowCount - 1, rowCount),
|
||||||
|
selected = current != null && !isPlainPreset,
|
||||||
|
onClick = { customMode = true },
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
Column(
|
||||||
|
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||||
|
modifier = Modifier.padding(horizontal = 24.dp),
|
||||||
|
) {
|
||||||
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
|
Text(
|
||||||
|
text = stringResource(R.string.event_edit_recurrence_every),
|
||||||
|
style = MaterialTheme.typography.titleMedium,
|
||||||
|
)
|
||||||
|
Spacer(Modifier.width(12.dp))
|
||||||
|
DialogAmountField(
|
||||||
|
value = intervalText,
|
||||||
|
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] },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (freq == RecurrenceFreq.Weekly) {
|
||||||
|
WeekdayToggleRow(
|
||||||
|
selected = daysMask.toDaySet(),
|
||||||
|
onToggle = { day -> daysMask = daysMask xor day.toMaskBit() },
|
||||||
|
locale = locale,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Text(
|
||||||
|
text = stringResource(R.string.event_edit_recurrence_ends),
|
||||||
|
style = MaterialTheme.typography.bodyMedium,
|
||||||
|
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
GroupedRow(
|
||||||
|
title = stringResource(R.string.event_edit_recurrence_end_never),
|
||||||
|
position = positionOf(0, 3),
|
||||||
|
selected = endMode == RecurrenceEndMode.Never,
|
||||||
|
onClick = { endMode = RecurrenceEndMode.Never },
|
||||||
|
)
|
||||||
|
GroupedRow(
|
||||||
|
title = stringResource(R.string.event_edit_recurrence_end_until),
|
||||||
|
summary = untilDate?.let {
|
||||||
|
remember(it, locale) {
|
||||||
|
DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM)
|
||||||
|
.withLocale(locale).format(it.toJavaLocalDate())
|
||||||
|
}
|
||||||
|
},
|
||||||
|
position = positionOf(1, 3),
|
||||||
|
selected = endMode == RecurrenceEndMode.Until,
|
||||||
|
onClick = {
|
||||||
|
endMode = RecurrenceEndMode.Until
|
||||||
|
showUntilPicker = true
|
||||||
|
},
|
||||||
|
)
|
||||||
|
GroupedRow(
|
||||||
|
title = stringResource(R.string.event_edit_recurrence_end_count),
|
||||||
|
position = positionOf(2, 3),
|
||||||
|
selected = endMode == RecurrenceEndMode.Count,
|
||||||
|
onClick = { endMode = RecurrenceEndMode.Count },
|
||||||
|
)
|
||||||
|
if (endMode == RecurrenceEndMode.Count) {
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = Modifier.padding(horizontal = 24.dp, vertical = 4.dp),
|
||||||
|
) {
|
||||||
|
DialogAmountField(
|
||||||
|
value = countText,
|
||||||
|
onValueChange = { countText = it },
|
||||||
|
placeholder = "10",
|
||||||
|
)
|
||||||
|
Spacer(Modifier.width(12.dp))
|
||||||
|
Text(
|
||||||
|
text = stringResource(R.string.event_edit_recurrence_times),
|
||||||
|
style = MaterialTheme.typography.titleMedium,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (showUntilPicker) {
|
if (showUntilPicker) {
|
||||||
CalendarDatePickerDialog(
|
CalendarDatePickerDialog(
|
||||||
@@ -1701,24 +1701,14 @@ private fun VisibilityPickerDialog(
|
|||||||
onSelect: (AccessLevel) -> Unit,
|
onSelect: (AccessLevel) -> Unit,
|
||||||
onDismiss: () -> Unit,
|
onDismiss: () -> Unit,
|
||||||
) {
|
) {
|
||||||
AlertDialog(
|
OptionPicker(
|
||||||
onDismissRequest = onDismiss,
|
title = stringResource(R.string.event_edit_visibility),
|
||||||
title = { Text(stringResource(R.string.event_edit_visibility)) },
|
options = AccessLevel.entries.toList(),
|
||||||
text = {
|
selected = selected,
|
||||||
Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
|
label = { stringResource(accessLevelLabel(it)) },
|
||||||
AccessLevel.entries.forEach { level ->
|
onSelect = onSelect,
|
||||||
OptionCard(
|
onDismiss = onDismiss,
|
||||||
label = stringResource(accessLevelLabel(level)),
|
leading = { Icon(imageVector = accessLevelIcon(it), contentDescription = null) },
|
||||||
onClick = { onSelect(level) },
|
|
||||||
icon = accessLevelIcon(level),
|
|
||||||
selected = level == selected,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
confirmButton = {
|
|
||||||
TextButton(onClick = onDismiss) { Text(stringResource(R.string.dialog_cancel)) }
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1741,51 +1731,48 @@ private fun ColorPickerDialog(
|
|||||||
onDismiss: () -> Unit,
|
onDismiss: () -> Unit,
|
||||||
) {
|
) {
|
||||||
val dark = isSystemInDarkTheme()
|
val dark = isSystemInDarkTheme()
|
||||||
AlertDialog(
|
FullScreenPicker(
|
||||||
onDismissRequest = onDismiss,
|
title = stringResource(R.string.event_edit_color),
|
||||||
title = { Text(stringResource(R.string.event_edit_color)) },
|
onDismiss = onDismiss,
|
||||||
text = {
|
actions = {
|
||||||
Column(verticalArrangement = Arrangement.spacedBy(12.dp)) {
|
if (hasExplicitColor) {
|
||||||
if (palette.isNotEmpty()) {
|
|
||||||
ColorSwatchRow(
|
|
||||||
colors = palette.map { it.argb },
|
|
||||||
selected = selected,
|
|
||||||
onSelect = { argb ->
|
|
||||||
palette.firstOrNull { it.argb == argb }
|
|
||||||
?.let { onPickKey(it.key, it.argb) }
|
|
||||||
},
|
|
||||||
dark = dark,
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
ColorSwatchRow(
|
|
||||||
colors = CalendarColorPalette.all,
|
|
||||||
selected = selected,
|
|
||||||
onSelect = onPickRaw,
|
|
||||||
dark = dark,
|
|
||||||
)
|
|
||||||
if (syncWarning) {
|
|
||||||
Text(
|
|
||||||
text = stringResource(R.string.event_edit_color_sync_warning),
|
|
||||||
style = MaterialTheme.typography.bodySmall,
|
|
||||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
confirmButton = {
|
|
||||||
TextButton(onClick = onDismiss) { Text(stringResource(R.string.dialog_cancel)) }
|
|
||||||
},
|
|
||||||
dismissButton = if (hasExplicitColor) {
|
|
||||||
{
|
|
||||||
TextButton(onClick = onClear) {
|
TextButton(onClick = onClear) {
|
||||||
Text(stringResource(R.string.event_edit_color_reset))
|
Text(stringResource(R.string.event_edit_color_reset))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
null
|
|
||||||
},
|
},
|
||||||
)
|
) {
|
||||||
|
Column(
|
||||||
|
verticalArrangement = Arrangement.spacedBy(12.dp),
|
||||||
|
modifier = Modifier.padding(horizontal = 24.dp, vertical = 8.dp),
|
||||||
|
) {
|
||||||
|
if (palette.isNotEmpty()) {
|
||||||
|
ColorSwatchRow(
|
||||||
|
colors = palette.map { it.argb },
|
||||||
|
selected = selected,
|
||||||
|
onSelect = { argb ->
|
||||||
|
palette.firstOrNull { it.argb == argb }
|
||||||
|
?.let { onPickKey(it.key, it.argb) }
|
||||||
|
},
|
||||||
|
dark = dark,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
ColorSwatchRow(
|
||||||
|
colors = CalendarColorPalette.all,
|
||||||
|
selected = selected,
|
||||||
|
onSelect = onPickRaw,
|
||||||
|
dark = dark,
|
||||||
|
)
|
||||||
|
if (syncWarning) {
|
||||||
|
Text(
|
||||||
|
text = stringResource(R.string.event_edit_color_sync_warning),
|
||||||
|
style = MaterialTheme.typography.bodySmall,
|
||||||
|
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun accessLevelIcon(level: AccessLevel): ImageVector = when (level) {
|
private fun accessLevelIcon(level: AccessLevel): ImageVector = when (level) {
|
||||||
|
|||||||
@@ -160,7 +160,7 @@ private enum class ChipAccent { Neutral, Primary, Tertiary }
|
|||||||
* Settings (M4), restructured in v2.3 into a category hub with sub-screens.
|
* Settings (M4), restructured in v2.3 into a category hub with sub-screens.
|
||||||
* Both the hub and the sub-screens use a collapsing [LargeTopAppBar] and the
|
* Both the hub and the sub-screens use a collapsing [LargeTopAppBar] and the
|
||||||
* grouped-row card system. Calendars opens the separate manager hoisted in
|
* grouped-row card system. Calendars opens the separate manager hoisted in
|
||||||
* [CalendarHost]; Language opens an inline OptionCard dialog; About is a card
|
* [CalendarHost]; Language opens a full-screen picker; About is a card
|
||||||
* at the top. A full-screen destination; [onBack] pops it.
|
* at the top. A full-screen destination; [onBack] pops it.
|
||||||
*/
|
*/
|
||||||
@Composable
|
@Composable
|
||||||
|
|||||||
Submodule floret-kit updated: 55ad536513...e1919cab83
Reference in New Issue
Block a user