From 7c3b62eb0dfd1cff9aafc93fabd86ad2a075630e Mon Sep 17 00:00:00 2001 From: Jean-Luc Makiola Date: Fri, 2 Oct 2026 18:17:36 +0200 Subject: [PATCH] feat: setting to default a new task's start to today (#31) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A new Settings → Task form toggle, off by default, pre-fills a fresh task's start with the current moment instead of leaving it blank. Closes #27 Co-authored-by: Jean-Luc Makiola Reviewed-on: https://codeberg.org/jlmakiola/agendula/pulls/31 --- .../agendula/data/prefs/SettingsPrefs.kt | 6 ++++++ .../agendula/ui/edit/TaskEditViewModel.kt | 2 ++ .../agendula/ui/settings/SettingsViewModel.kt | 1 + .../agendula/ui/settings/TaskFormScreen.kt | 12 ++++++++++++ app/src/main/res/values/strings.xml | 2 ++ 5 files changed, 23 insertions(+) diff --git a/app/src/main/java/de/jeanlucmakiola/agendula/data/prefs/SettingsPrefs.kt b/app/src/main/java/de/jeanlucmakiola/agendula/data/prefs/SettingsPrefs.kt index 733745d..baaaaeb 100644 --- a/app/src/main/java/de/jeanlucmakiola/agendula/data/prefs/SettingsPrefs.kt +++ b/app/src/main/java/de/jeanlucmakiola/agendula/data/prefs/SettingsPrefs.kt @@ -95,6 +95,8 @@ data class Settings( val pushEnabled: Boolean = true, /** Lists of the current store whose tasks the smart lists (and their counts) leave out. */ val hiddenFromSmartLists: Set = emptySet(), + /** Pre-fill a new task's start with today's date. */ + val defaultStartToday: Boolean = false, ) { /** [tasks] as [filter] shows them: a smart list drops the lists kept out of it. */ fun visibleIn(filter: TaskFilter, tasks: List): List = @@ -153,6 +155,7 @@ class SettingsPrefs @Inject constructor( .mapNotNull { entry -> entry.substringAfter("$mode:", "").toLongOrNull() } .toSet() }, + defaultStartToday = p[DEFAULT_START_TODAY] ?: false, ) } @@ -166,6 +169,8 @@ class SettingsPrefs @Inject constructor( suspend fun setAutofocusTitle(enabled: Boolean) = dataStore.edit { it[AUTOFOCUS_TITLE] = enabled } + suspend fun setDefaultStartToday(enabled: Boolean) = dataStore.edit { it[DEFAULT_START_TODAY] = enabled } + suspend fun setTimeFormat(pref: TimeFormatPref) = dataStore.edit { it[TIME_FORMAT] = pref.name } suspend fun setWeekStart(day: DayOfWeek?) = dataStore.edit { @@ -282,6 +287,7 @@ class SettingsPrefs @Inject constructor( val SYNC_INTERVAL = intPreferencesKey("sync_interval_minutes") val PUSH_ENABLED = booleanPreferencesKey("push_enabled") val SMART_LIST_HIDDEN = stringSetPreferencesKey("smart_list_hidden") + val DEFAULT_START_TODAY = booleanPreferencesKey("default_start_today") } } diff --git a/app/src/main/java/de/jeanlucmakiola/agendula/ui/edit/TaskEditViewModel.kt b/app/src/main/java/de/jeanlucmakiola/agendula/ui/edit/TaskEditViewModel.kt index 2c75dec..058eee1 100644 --- a/app/src/main/java/de/jeanlucmakiola/agendula/ui/edit/TaskEditViewModel.kt +++ b/app/src/main/java/de/jeanlucmakiola/agendula/ui/edit/TaskEditViewModel.kt @@ -26,6 +26,7 @@ import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.first import kotlinx.coroutines.launch import javax.inject.Inject +import kotlin.time.Clock import kotlin.time.Instant /** @@ -135,6 +136,7 @@ class TaskEditViewModel @Inject constructor( isNew = true, autofocusTitle = settings.autofocusTitle, listId = defaultList, + start = if (settings.defaultStartToday) Clock.System.now() else null, parentId = parentId, lists = lists, parentCandidates = loadParents(defaultList, selfId = null), diff --git a/app/src/main/java/de/jeanlucmakiola/agendula/ui/settings/SettingsViewModel.kt b/app/src/main/java/de/jeanlucmakiola/agendula/ui/settings/SettingsViewModel.kt index e74a509..7171ae1 100644 --- a/app/src/main/java/de/jeanlucmakiola/agendula/ui/settings/SettingsViewModel.kt +++ b/app/src/main/java/de/jeanlucmakiola/agendula/ui/settings/SettingsViewModel.kt @@ -241,6 +241,7 @@ class SettingsViewModel @Inject constructor( fun setSnoozeMinutes(minutes: Int) = viewModelScope.launch { prefs.setSnoozeMinutes(minutes) } fun setShowAddSubtaskRow(show: Boolean) = viewModelScope.launch { prefs.setShowAddSubtaskRow(show) } fun setBottomAddBar(enabled: Boolean) = viewModelScope.launch { prefs.setBottomAddBar(enabled) } + fun setDefaultStartToday(enabled: Boolean) = viewModelScope.launch { prefs.setDefaultStartToday(enabled) } /** Toggle whether [field] shows by default on a new task's edit form. */ fun setFormFieldDefault(field: TaskFormField, enabled: Boolean) = viewModelScope.launch { diff --git a/app/src/main/java/de/jeanlucmakiola/agendula/ui/settings/TaskFormScreen.kt b/app/src/main/java/de/jeanlucmakiola/agendula/ui/settings/TaskFormScreen.kt index d8d7268..cd1c891 100644 --- a/app/src/main/java/de/jeanlucmakiola/agendula/ui/settings/TaskFormScreen.kt +++ b/app/src/main/java/de/jeanlucmakiola/agendula/ui/settings/TaskFormScreen.kt @@ -99,6 +99,18 @@ internal fun TaskFormScreen( }, onClick = { viewModel.setShowAddSubtaskRow(!state.settings.showAddSubtaskRow) }, ) + GroupedRow( + title = stringResource(R.string.settings_default_start_today), + summary = stringResource(R.string.settings_default_start_today_hint), + position = Position.Middle, + trailing = { + Switch( + checked = state.settings.defaultStartToday, + onCheckedChange = viewModel::setDefaultStartToday, + ) + }, + onClick = { viewModel.setDefaultStartToday(!state.settings.defaultStartToday) }, + ) GroupedRow( title = stringResource(R.string.settings_bottom_add_bar), summary = stringResource(R.string.settings_bottom_add_bar_hint), diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f89e585..0daf5fb 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -430,6 +430,8 @@ First available list Show \"add a subtask\" row An add field at the end of an expanded task\'s subtasks + Default start to today + Pre-fill a new task\'s start with today\'s date Bottom quick-add bar Add tasks from a bar pinned to the bottom of a list, instead of the floating button