Read settings from one prefs snapshot

This commit is contained in:
2026-10-16 13:04:47 +02:00
parent 0f1ed9f4d6
commit 26a408aab6
2 changed files with 118 additions and 340 deletions
@@ -116,7 +116,7 @@ data class SettingsUiState(
/**
* State for the contact special-dates sub-page (issue #15). Exposed as its own
* flow rather than folded into [SettingsUiState] (whose combine is already full).
* flow rather than folded into [SettingsUiState].
* [titleTemplates] is always populated — a blank stored template resolves to the
* localized default so the editor never shows an empty field.
*/
@@ -6,6 +6,7 @@ import android.os.Build
import androidx.glance.appwidget.GlanceAppWidgetManager
import androidx.glance.appwidget.state.updateAppWidgetState
import androidx.glance.appwidget.updateAll
import androidx.datastore.preferences.core.Preferences
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
@@ -23,7 +24,14 @@ import de.jeanlucmakiola.floret.di.IoDispatcher
import de.jeanlucmakiola.floret.reminders.ReminderOverride
import de.jeanlucmakiola.floret.reminders.reminderOverrideFor
import de.jeanlucmakiola.calendula.data.prefs.PastEventDisplay
import de.jeanlucmakiola.calendula.data.prefs.SettingsKeys
import de.jeanlucmakiola.calendula.data.prefs.SettingsPrefs
import de.jeanlucmakiola.calendula.data.prefs.specialDatesCalendars
import de.jeanlucmakiola.calendula.data.prefs.specialDatesStatus
import de.jeanlucmakiola.calendula.data.prefs.specialDatesTitleTemplates
import de.jeanlucmakiola.calendula.data.prefs.specialDatesTypes
import de.jeanlucmakiola.calendula.data.prefs.timelineHours
import de.jeanlucmakiola.floret.prefs.get
import de.jeanlucmakiola.calendula.data.prefs.SpecialDatesStalledReason
import de.jeanlucmakiola.floret.prefs.ThemeMode
import de.jeanlucmakiola.calendula.data.prefs.TimeFormatPref
@@ -36,7 +44,6 @@ import de.jeanlucmakiola.calendula.domain.contacts.SpecialDateType
import de.jeanlucmakiola.calendula.ui.agenda.AgendaRange
import de.jeanlucmakiola.calendula.ui.agenda.storageValue
import de.jeanlucmakiola.calendula.ui.common.CalendarView
import de.jeanlucmakiola.calendula.ui.common.QuickSwitchConfig
import de.jeanlucmakiola.calendula.ui.common.TimelineHours
import de.jeanlucmakiola.calendula.ui.common.TimelineScale
import de.jeanlucmakiola.calendula.ui.month.MonthViewStyle
@@ -89,163 +96,66 @@ class SettingsViewModel @Inject constructor(
.catch { emit(emptyList()) }
val state: StateFlow<SettingsUiState> =
combine(
// combine() types up to five flows, so the prefs split into two
// groups that fold together in the outer combine.
combine(
prefs.themeMode,
prefs.dynamicColor,
prefs.weekStart,
prefs.defaultFormFields,
prefs.remindersEnabled,
) { theme, dynamic, weekStart, formFields, reminders ->
SettingsUiState(
themeMode = theme,
dynamicColor = dynamic && dynamicColorAvailable,
dynamicColorAvailable = dynamicColorAvailable,
weekStart = weekStart,
defaultFormFields = formFields,
remindersEnabled = reminders,
)
},
combine(
prefs.allowColorOnUnsupportedCalendars,
prefs.defaultReminderMinutes,
prefs.defaultAllDayReminderMinutes,
prefs.allDayReminderTimeMinutes,
prefs.snoozeMinutes,
) { allowColor, defaultReminder, allDayReminder, allDayReminderTime, snooze ->
ReminderDefaults(
allowColor, defaultReminder, allDayReminder, allDayReminderTime, snooze,
)
},
combine(
prefs.perCalendarReminderOverride,
prefs.perCalendarAllDayReminderOverride,
writableCalendars,
prefs.managedCalendarIds,
// The new-event duration defaults (#54) fold into one flow so they
// fit this group — the outer combine is at its five-arg limit.
combine(
prefs.defaultEventDurationMinutes,
prefs.perCalendarEventDuration,
) { duration, perCalendar -> EventDurations(duration, perCalendar) },
) { overrides, allDayOverrides, calendars, managedIds, durations ->
ReminderOverrides(overrides, allDayOverrides, calendars, managedIds, durations)
},
combine(
prefs.defaultView,
prefs.agendaScreenRange,
prefs.agendaWidgetRange,
prefs.timeFormat,
// Display toggles folded into one flow so they fit this group —
// the outer combine is already at its five-arg limit.
combine(
prefs.showHourGrid,
prefs.showWeekNumbers,
prefs.agendaShowToday,
prefs.softenCalendarColors,
combine(
prefs.todayButtonInToolbar,
combine(prefs.dragToReschedule, prefs.tapOpensEditor, ::Pair),
prefs.multiDayCount,
::Triple,
),
) { hourLines, weekNumbers, showToday, soften, (todayInToolbar, gestures, multiDay) ->
DisplayToggles(
hourLines, weekNumbers, showToday, soften, todayInToolbar,
dragToReschedule = gestures.first,
tapOpensEditor = gestures.second,
multiDayCount = multiDay,
)
},
) { view, screenRange, widgetRange, timeFormat, toggles ->
ViewSettings(
view, screenRange, widgetRange, timeFormat,
showHourGrid = toggles.showHourGrid,
showWeekNumbers = toggles.showWeekNumbers,
agendaShowToday = toggles.agendaShowToday,
softenColors = toggles.softenColors,
todayButtonInToolbar = toggles.todayButtonInToolbar,
dragToReschedule = toggles.dragToReschedule,
tapOpensEditor = toggles.tapOpensEditor,
multiDayCount = toggles.multiDayCount,
)
},
combine(
prefs.agendaShowRangeBar,
prefs.autofocusEventTitle,
prefs.pastEventDisplay,
prefs.dimCompletedEvents,
// View customisation (#24) folded into one flow so it fits this
// group — the outer combine is already at its five-arg limit.
combine(
prefs.quickSwitchConfig,
prefs.drawerViewOrder,
prefs.monthViewStyle,
prefs.widgetSize,
combine(prefs.timelineScale, prefs.timelineHours, ::Pair),
) { quickSwitch, drawer, monthStyle, widgetSize, (timelineScale, timelineHours) ->
ViewCustomization(
quickSwitch, drawer, monthStyle, widgetSize, timelineScale, timelineHours,
)
},
) { showRangeBar, autofocus, pastEvents, dimCompleted, viewCustomization ->
MiscSettings(showRangeBar, autofocus, pastEvents, dimCompleted, viewCustomization)
},
) { base, defaults, overrides, views, misc ->
base.copy(
defaultView = views.defaultView,
agendaScreenRange = views.agendaScreenRange,
agendaWidgetRange = views.agendaWidgetRange,
timeFormat = views.timeFormat,
showHourGrid = views.showHourGrid,
showWeekNumbers = views.showWeekNumbers,
agendaShowToday = views.agendaShowToday,
softenColors = views.softenColors,
todayButtonInToolbar = views.todayButtonInToolbar,
dragToReschedule = views.dragToReschedule,
tapOpensEditor = views.tapOpensEditor,
multiDayCount = views.multiDayCount,
agendaShowRangeBar = misc.showRangeBar,
autofocusEventTitle = misc.autofocusEventTitle,
pastEventDisplay = misc.pastEventDisplay,
dimCompletedEvents = misc.dimCompletedEvents,
quickSwitchConfig = misc.viewCustomization.quickSwitch,
drawerViewOrder = misc.viewCustomization.drawerOrder,
monthViewStyle = misc.viewCustomization.monthViewStyle,
widgetSize = misc.viewCustomization.widgetSize,
timelineScale = misc.viewCustomization.timelineScale,
timelineHours = misc.viewCustomization.timelineHours,
allowColorOnUnsupportedCalendars = defaults.allowColor,
defaultReminderMinutes = defaults.defaultReminder,
defaultAllDayReminderMinutes = defaults.allDayReminder,
allDayReminderTimeMinutes = defaults.allDayReminderTime,
snoozeMinutes = defaults.snoozeMinutes,
perCalendarReminderOverride = overrides.timed,
perCalendarAllDayReminderOverride = overrides.allDay,
writableCalendars = overrides.calendars,
managedCalendarIds = overrides.managedIds,
defaultEventDurationMinutes = overrides.durations.default,
perCalendarEventDuration = overrides.durations.perCalendar,
combine(prefs.data, writableCalendars) { stored, calendars -> stored.toUiState(calendars) }
.stateWhileSubscribed(
scope = viewModelScope,
initialValue = SettingsUiState(dynamicColorAvailable = dynamicColorAvailable),
)
}.stateWhileSubscribed(
scope = viewModelScope,
initialValue = SettingsUiState(dynamicColorAvailable = dynamicColorAvailable),
)
private fun Preferences.toUiState(calendars: List<CalendarSource>) = SettingsUiState(
themeMode = this[SettingsKeys.themeMode],
dynamicColor = this[SettingsKeys.dynamicColor] && dynamicColorAvailable,
dynamicColorAvailable = dynamicColorAvailable,
softenColors = this[SettingsKeys.softenCalendarColors],
weekStart = this[SettingsKeys.weekStart],
timeFormat = this[SettingsKeys.timeFormat],
showHourGrid = this[SettingsKeys.showHourGrid],
multiDayCount = this[SettingsKeys.multiDayCount],
pastEventDisplay = this[SettingsKeys.pastEventDisplay],
dimCompletedEvents = this[SettingsKeys.dimCompletedEvents],
showWeekNumbers = this[SettingsKeys.showWeekNumbers],
todayButtonInToolbar = this[SettingsKeys.todayButtonInToolbar],
dragToReschedule = this[SettingsKeys.dragToReschedule],
tapOpensEditor = this[SettingsKeys.tapOpensEditor],
agendaScreenRange = this[SettingsKeys.agendaScreenRange],
agendaWidgetRange = this[SettingsKeys.agendaWidgetRange],
agendaShowToday = this[SettingsKeys.agendaShowToday],
agendaShowRangeBar = this[SettingsKeys.agendaShowRangeBar],
widgetSize = this[SettingsKeys.widgetSize],
defaultView = this[SettingsKeys.defaultView],
quickSwitchConfig = this[SettingsKeys.quickSwitchConfig],
monthViewStyle = this[SettingsKeys.monthViewStyle],
timelineScale = this[SettingsKeys.timelineScale],
timelineHours = timelineHours,
drawerViewOrder = this[SettingsKeys.drawerViewOrder],
defaultFormFields = this[SettingsKeys.defaultFormFields],
autofocusEventTitle = this[SettingsKeys.autofocusEventTitle],
defaultEventDurationMinutes = this[SettingsKeys.defaultEventDurationMinutes],
perCalendarEventDuration = this[SettingsKeys.perCalendarEventDuration],
remindersEnabled = this[SettingsKeys.remindersEnabled],
defaultReminderMinutes = this[SettingsKeys.defaultReminderMinutes],
defaultAllDayReminderMinutes = this[SettingsKeys.defaultAllDayReminderMinutes],
allDayReminderTimeMinutes = this[SettingsKeys.allDayReminderTimeMinutes],
snoozeMinutes = this[SettingsKeys.snoozeMinutes],
perCalendarReminderOverride = this[SettingsKeys.perCalendarReminderOverride],
perCalendarAllDayReminderOverride = this[SettingsKeys.perCalendarAllDayReminderOverride],
writableCalendars = calendars,
allowColorOnUnsupportedCalendars = this[SettingsKeys.allowColorOnUnsupportedCalendars],
managedCalendarIds = specialDatesCalendars.values.toSet(),
)
/**
* The app-wide custom-font choice (issue #19). Its own flow — both this
* screen and [MainActivity] (which builds the typography) read it
* independently of the main settings combine.
* independently of the main settings state.
*/
val fontState: StateFlow<AppFontSettings> = combine(
prefs.brandFont,
prefs.plainFont,
prefs.brandFontStamp,
prefs.plainFontStamp,
) { brand, plain, brandStamp, plainStamp ->
AppFontSettings(brand = brand, plain = plain, brandStamp = brandStamp, plainStamp = plainStamp)
val fontState: StateFlow<AppFontSettings> = prefs.data.map {
AppFontSettings(
brand = it[SettingsKeys.brandFont],
plain = it[SettingsKeys.plainFont],
brandStamp = it[SettingsKeys.brandFontStamp],
plainStamp = it[SettingsKeys.plainFontStamp],
)
}.stateWhileSubscribed(
scope = viewModelScope,
initialValue = AppFontSettings(),
@@ -275,100 +185,26 @@ class SettingsViewModel @Inject constructor(
// stale read and can leave the widget on an intermediate value.
private val widgetRefreshMutex = Mutex()
private data class ReminderDefaults(
val allowColor: Boolean,
val defaultReminder: List<Int>,
val allDayReminder: List<Int>,
val allDayReminderTime: Int,
val snoozeMinutes: Int,
)
private data class ReminderOverrides(
val timed: Map<Long, List<Int>>,
val allDay: Map<Long, List<Int>>,
val calendars: List<CalendarSource>,
val managedIds: Set<Long>,
val durations: EventDurations,
)
private data class EventDurations(
val default: Int,
val perCalendar: Map<Long, Int>,
)
private data class ViewSettings(
val defaultView: CalendarView,
val agendaScreenRange: AgendaRange,
val agendaWidgetRange: AgendaRange,
val timeFormat: TimeFormatPref,
val showHourGrid: Boolean,
val showWeekNumbers: Boolean,
val agendaShowToday: Boolean,
val softenColors: Boolean,
val todayButtonInToolbar: Boolean,
val dragToReschedule: Boolean,
val tapOpensEditor: Boolean,
val multiDayCount: Int,
)
private data class DisplayToggles(
val showHourGrid: Boolean,
val showWeekNumbers: Boolean,
val agendaShowToday: Boolean,
val softenColors: Boolean,
val todayButtonInToolbar: Boolean,
val dragToReschedule: Boolean,
val tapOpensEditor: Boolean,
val multiDayCount: Int,
)
private data class MiscSettings(
val showRangeBar: Boolean,
val autofocusEventTitle: Boolean,
val pastEventDisplay: PastEventDisplay,
val dimCompletedEvents: Boolean,
val viewCustomization: ViewCustomization,
)
private data class ViewCustomization(
val quickSwitch: QuickSwitchConfig,
val drawerOrder: List<CalendarView>,
val monthViewStyle: MonthViewStyle,
val widgetSize: WidgetSize,
val timelineScale: TimelineScale,
val timelineHours: TimelineHours,
)
/** Contact special-dates sub-page (issue #15); its own flow — the main state is full. */
val specialDatesState: StateFlow<SpecialDatesUiState> = combine(
combine(
prefs.specialDatesEnabled,
prefs.specialDatesTypes,
prefs.specialDatesTitleTemplates,
prefs.specialDatesShowYear,
prefs.specialDatesStatus,
) { enabled, types, templates, showYear, status ->
SpecialDatesUiState(
enabled = enabled,
types = types,
// A blank stored template resolves to the localized default so the
// editor always shows something sensible.
titleTemplates = SpecialDateType.entries.associateWith { type ->
specialDatesSpec.resolveTitleTemplate(type, templates)
},
showYear = showYear,
stalledPermission = status.stalled == SpecialDatesStalledReason.PermissionRevoked,
lastRun = status.lastRun,
)
},
prefs.specialDatesCalendars,
prefs.perCalendarAllDayReminderOverride,
) { base, calendars, allDayOverrides ->
base.copy(
/** Contact special-dates sub-page (issue #15). */
val specialDatesState: StateFlow<SpecialDatesUiState> = prefs.data.map { stored ->
val templates = stored.specialDatesTitleTemplates
val allDayOverrides = stored[SettingsKeys.perCalendarAllDayReminderOverride]
val status = stored.specialDatesStatus
SpecialDatesUiState(
enabled = stored[SettingsKeys.specialDatesEnabled],
types = stored.specialDatesTypes,
// A blank stored template resolves to the localized default so the
// editor always shows something sensible.
titleTemplates = SpecialDateType.entries.associateWith { type ->
specialDatesSpec.resolveTitleTemplate(type, templates)
},
// An override is always seeded on creation; present-empty = None.
reminderChoices = calendars.mapValues { (_, calendarId) ->
reminderChoices = stored.specialDatesCalendars.mapValues { (_, calendarId) ->
allDayOverrides.reminderOverrideFor(calendarId)
},
showYear = stored[SettingsKeys.specialDatesShowYear],
stalledPermission = status.stalled == SpecialDatesStalledReason.PermissionRevoked,
lastRun = status.lastRun,
)
}.stateWhileSubscribed(
scope = viewModelScope,
@@ -427,13 +263,9 @@ class SettingsViewModel @Inject constructor(
/** Kick off an immediate reconcile (the "Sync now" action). */
fun syncSpecialDatesNow() = SpecialDatesScheduler.runNow(appContext)
fun setThemeMode(mode: ThemeMode) {
viewModelScope.launch { prefs.setThemeMode(mode) }
}
fun setThemeMode(mode: ThemeMode) = save { setThemeMode(mode) }
fun setDynamicColor(enabled: Boolean) {
viewModelScope.launch { prefs.setDynamicColor(enabled) }
}
fun setDynamicColor(enabled: Boolean) = save { setDynamicColor(enabled) }
fun setSoftenColors(enabled: Boolean) {
viewModelScope.launch {
@@ -446,12 +278,10 @@ class SettingsViewModel @Inject constructor(
}
}
fun setFont(role: FontRole, token: String) {
viewModelScope.launch {
when (role) {
FontRole.BRAND -> prefs.setBrandFont(token)
FontRole.PLAIN -> prefs.setPlainFont(token)
}
fun setFont(role: FontRole, token: String) = save {
when (role) {
FontRole.BRAND -> setBrandFont(token)
FontRole.PLAIN -> setPlainFont(token)
}
}
@@ -486,9 +316,7 @@ class SettingsViewModel @Inject constructor(
}
}
fun setAgendaScreenRange(range: AgendaRange) {
viewModelScope.launch { prefs.setAgendaScreenRange(range) }
}
fun setAgendaScreenRange(range: AgendaRange) = save { setAgendaScreenRange(range) }
fun setAgendaWidgetRange(range: AgendaRange) {
viewModelScope.launch {
@@ -505,9 +333,7 @@ class SettingsViewModel @Inject constructor(
}
}
fun setAgendaShowRangeBar(enabled: Boolean) {
viewModelScope.launch { prefs.setAgendaShowRangeBar(enabled) }
}
fun setAgendaShowRangeBar(enabled: Boolean) = save { setAgendaShowRangeBar(enabled) }
/**
* Set the size the agenda widget draws its text at (#51), via the same
@@ -541,33 +367,19 @@ class SettingsViewModel @Inject constructor(
}
}
fun setTimeFormat(pref: TimeFormatPref) {
viewModelScope.launch { prefs.setTimeFormat(pref) }
}
fun setTimeFormat(pref: TimeFormatPref) = save { setTimeFormat(pref) }
fun setMultiDayCount(count: Int) {
viewModelScope.launch { prefs.setMultiDayCount(count) }
}
fun setMultiDayCount(count: Int) = save { setMultiDayCount(count) }
fun setShowHourGrid(enabled: Boolean) {
viewModelScope.launch { prefs.setShowHourGrid(enabled) }
}
fun setShowHourGrid(enabled: Boolean) = save { setShowHourGrid(enabled) }
fun setShowWeekNumbers(enabled: Boolean) {
viewModelScope.launch { prefs.setShowWeekNumbers(enabled) }
}
fun setShowWeekNumbers(enabled: Boolean) = save { setShowWeekNumbers(enabled) }
fun setTodayButtonInToolbar(enabled: Boolean) {
viewModelScope.launch { prefs.setTodayButtonInToolbar(enabled) }
}
fun setTodayButtonInToolbar(enabled: Boolean) = save { setTodayButtonInToolbar(enabled) }
fun setDragToReschedule(enabled: Boolean) {
viewModelScope.launch { prefs.setDragToReschedule(enabled) }
}
fun setDragToReschedule(enabled: Boolean) = save { setDragToReschedule(enabled) }
fun setTapOpensEditor(enabled: Boolean) {
viewModelScope.launch { prefs.setTapOpensEditor(enabled) }
}
fun setTapOpensEditor(enabled: Boolean) = save { setTapOpensEditor(enabled) }
/**
* Switch the launcher label (#44). The card highlights at once, then settles
@@ -598,53 +410,33 @@ class SettingsViewModel @Inject constructor(
}
}
fun setDimCompletedEvents(enabled: Boolean) {
viewModelScope.launch { prefs.setDimCompletedEvents(enabled) }
}
fun setDimCompletedEvents(enabled: Boolean) = save { setDimCompletedEvents(enabled) }
fun setDefaultView(view: CalendarView) {
viewModelScope.launch { prefs.setDefaultView(view) }
}
fun setDefaultView(view: CalendarView) = save { setDefaultView(view) }
fun setFormFieldDefault(field: EventFormField, enabled: Boolean) {
viewModelScope.launch { prefs.setFormFieldDefault(field, enabled) }
}
fun setFormFieldDefault(field: EventFormField, enabled: Boolean) = save { setFormFieldDefault(field, enabled) }
/**
* Enable or disable [view] in the quick-switch cycle, via an atomic
* read-modify-write so a concurrent reorder can't clobber it. Any number of
* views may be turned off; below two the pill hides itself (#150).
*/
fun setQuickSwitchViewEnabled(view: CalendarView, enabled: Boolean) {
viewModelScope.launch {
prefs.updateQuickSwitch { config ->
config.copy(
enabled = if (enabled) config.enabled + view else config.enabled - view,
)
}
fun setQuickSwitchViewEnabled(view: CalendarView, enabled: Boolean) = save {
updateQuickSwitch { config ->
config.copy(enabled = if (enabled) config.enabled + view else config.enabled - view)
}
}
/** Reorder the quick-switch views (atomic read-modify-write; keeps the enabled set). */
fun setQuickSwitchOrder(order: List<CalendarView>) {
viewModelScope.launch { prefs.updateQuickSwitch { it.copy(order = order) } }
}
fun setQuickSwitchOrder(order: List<CalendarView>) = save { updateQuickSwitch { it.copy(order = order) } }
fun setMonthViewStyle(style: MonthViewStyle) {
viewModelScope.launch { prefs.setMonthViewStyle(style) }
}
fun setMonthViewStyle(style: MonthViewStyle) = save { setMonthViewStyle(style) }
fun setTimelineScale(scale: TimelineScale) {
viewModelScope.launch { prefs.setTimelineScale(scale) }
}
fun setTimelineScale(scale: TimelineScale) = save { setTimelineScale(scale) }
fun setTimelineHours(hours: TimelineHours) {
viewModelScope.launch { prefs.setTimelineHours(hours) }
}
fun setTimelineHours(hours: TimelineHours) = save { setTimelineHours(hours) }
fun setDrawerViewOrder(order: List<CalendarView>) {
viewModelScope.launch { prefs.setDrawerViewOrder(order) }
}
fun setDrawerViewOrder(order: List<CalendarView>) = save { setDrawerViewOrder(order) }
/**
* A scan follows the write: switching reminders off cancels the scan alarm,
@@ -657,26 +449,16 @@ class SettingsViewModel @Inject constructor(
}
}
fun setAutofocusEventTitle(enabled: Boolean) {
viewModelScope.launch { prefs.setAutofocusEventTitle(enabled) }
}
fun setAutofocusEventTitle(enabled: Boolean) = save { setAutofocusEventTitle(enabled) }
fun setDefaultEventDuration(minutes: Int) {
viewModelScope.launch { prefs.setDefaultEventDurationMinutes(minutes) }
}
fun setDefaultEventDuration(minutes: Int) = save { setDefaultEventDurationMinutes(minutes) }
/** [minutes] null clears the override, so the calendar inherits the default. */
fun setCalendarEventDuration(calendarId: Long, minutes: Int?) {
viewModelScope.launch { prefs.setCalendarEventDuration(calendarId, minutes) }
}
fun setCalendarEventDuration(calendarId: Long, minutes: Int?) = save { setCalendarEventDuration(calendarId, minutes) }
fun setDefaultReminderMinutes(minutes: List<Int>) {
viewModelScope.launch { prefs.setDefaultReminderMinutes(minutes) }
}
fun setDefaultReminderMinutes(minutes: List<Int>) = save { setDefaultReminderMinutes(minutes) }
fun setDefaultAllDayReminderMinutes(minutes: List<Int>) {
viewModelScope.launch { prefs.setDefaultAllDayReminderMinutes(minutes) }
}
fun setDefaultAllDayReminderMinutes(minutes: List<Int>) = save { setDefaultAllDayReminderMinutes(minutes) }
/** The armed alarm was planned for the old hour, so re-plan against the new one. */
fun setAllDayReminderTimeMinutes(minutesOfDay: Int) {
@@ -686,19 +468,15 @@ class SettingsViewModel @Inject constructor(
}
}
fun setSnoozeMinutes(minutes: Int) {
viewModelScope.launch { prefs.setSnoozeMinutes(minutes) }
}
fun setSnoozeMinutes(minutes: Int) = save { setSnoozeMinutes(minutes) }
fun setCalendarReminderOverride(calendarId: Long, override: ReminderOverride) {
viewModelScope.launch { prefs.setCalendarReminderOverride(calendarId, override) }
}
fun setCalendarReminderOverride(calendarId: Long, override: ReminderOverride) = save { setCalendarReminderOverride(calendarId, override) }
fun setCalendarAllDayReminderOverride(calendarId: Long, override: ReminderOverride) {
viewModelScope.launch { prefs.setCalendarAllDayReminderOverride(calendarId, override) }
}
fun setCalendarAllDayReminderOverride(calendarId: Long, override: ReminderOverride) = save { setCalendarAllDayReminderOverride(calendarId, override) }
fun setAllowColorOnUnsupportedCalendars(enabled: Boolean) {
viewModelScope.launch { prefs.setAllowColorOnUnsupportedCalendars(enabled) }
fun setAllowColorOnUnsupportedCalendars(enabled: Boolean) = save { setAllowColorOnUnsupportedCalendars(enabled) }
private fun save(write: suspend SettingsPrefs.() -> Unit) {
viewModelScope.launch { prefs.write() }
}
}