From a082da3ee7a470a660692654c47bf6c776597c05 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 12 Sep 2026 12:20:53 +0000 Subject: [PATCH] Tasks: colour the overview and edit sheets by the Settings > Colours axes PR #137 wired the task list card to the Settings > Colours spine+badge and icon axes, but the two sheets a tap and a long-press open (TaskOverviewSheet, EditTaskSheet) kept their own hardcoded chip and badge colours. The chore sheets already take badgeSwatch/iconSwatch; the task sheets were never given the parameters. Both task sheets now take the same two swatch parameters and resolve the header icon chip, the due badge and the category value chip through them, falling back to the urgency tone or the task accent exactly as TaskCard and the chore sheets do. TaskListScreen passes uiState.spineSwatchFor / iconSwatchFor at both call sites, so card and sheet always agree. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_01EA12n2jYUVdMNHPkuJborZ --- LESSONS.md | 16 ++++++++++++ .../dash/ui/components/EditTaskSheet.kt | 15 ++++++++--- .../dash/ui/components/TaskOverviewSheet.kt | 26 ++++++++++++++++--- .../dash/ui/screens/tasks/TaskListScreen.kt | 4 +++ .../unreleased/task-sheet-colour-axes.json | 6 +++++ 5 files changed, 60 insertions(+), 7 deletions(-) create mode 100644 changelog/unreleased/task-sheet-colour-axes.json diff --git a/LESSONS.md b/LESSONS.md index 38d4342..ae1afeb 100644 --- a/LESSONS.md +++ b/LESSONS.md @@ -1369,3 +1369,19 @@ rather than swallowing the event, so the card does not slide for no reason; and the reveal panel's label is a per-card function of the action (Wake vs Snooze, Restore vs Done, Turn off for a tag-alarm), not a property of the enum, which keeps the enum free of UI and testable. + +## 60. A colour axis is a seam that runs through the card *and* the sheets behind it + +Settings › Colours was wired into `TaskCard` (#137) and the list looked right, +but tapping a task still opened `TaskOverviewSheet` and `EditTaskSheet` with +their own hardcoded chip and badge colours. The chore side had already passed +`badgeSwatch` / `iconSwatch` into `ChoreOverviewSheet` and `EditChoreSheet`; the +task sheets were simply never given the parameters, so the "fixed" screen was +only fixed until the first tap. + +When a setting decides the colour of an element, the seam is every composable +that draws that element for the same item: the list card, the overview sheet, +the edit sheet, the search results, the Done section. Grep the screen's +`*Screen.kt` for every sheet it opens and check each takes the same swatch +parameters as its sibling on the other tab; the `*UiState.spineSwatchFor` / +`iconSwatchFor` helpers exist so every call site resolves the colour the same way. diff --git a/app/src/main/java/com/mapgie/dash/ui/components/EditTaskSheet.kt b/app/src/main/java/com/mapgie/dash/ui/components/EditTaskSheet.kt index b08a5be..97560bb 100644 --- a/app/src/main/java/com/mapgie/dash/ui/components/EditTaskSheet.kt +++ b/app/src/main/java/com/mapgie/dash/ui/components/EditTaskSheet.kt @@ -36,6 +36,7 @@ import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.unit.dp import com.mapgie.dash.data.model.DuePeriod +import com.mapgie.dash.data.model.Swatch import com.mapgie.dash.data.model.TaskDraft import com.mapgie.dash.data.model.TaskDto import com.mapgie.dash.data.model.TaskDueType @@ -63,6 +64,8 @@ import com.mapgie.dash.ui.components.sheet.enumStateSaver import com.mapgie.dash.ui.components.sheet.jsonStateSaver import com.mapgie.dash.ui.theme.LocalTypeAccents import com.mapgie.dash.ui.theme.LucideIcons +import com.mapgie.dash.ui.theme.textColor +import com.mapgie.dash.ui.theme.tintColor import com.mapgie.dash.util.CalendarShareUtils import com.mapgie.dash.util.calendarEventForDate import com.mapgie.dash.util.calendarEventForInstant @@ -96,6 +99,10 @@ private const val DUE_PERIOD = TaskDueType.PERIOD fun EditTaskSheet( task: TaskDto?, icon: ImageVector, + /** Category colour for the category value chip (Settings › Colours spine+badge axis), or null. */ + badgeSwatch: Swatch?, + /** Category colour for the header icon chip (icon axis), or null for the task accent. */ + iconSwatch: Swatch?, owners: List, categories: List, onSave: (TaskInsert) -> Unit, @@ -307,8 +314,8 @@ fun EditTaskSheet( ) { SheetHeader( icon = icon, - chipContainer = accents.taskContainer, - chipContent = accents.onTaskContainer, + chipContainer = iconSwatch?.tintColor() ?: accents.taskContainer, + chipContent = iconSwatch?.textColor() ?: accents.onTaskContainer, eyebrow = if (isNew) "New task" else "Edit task", ) { TitleField( @@ -334,8 +341,8 @@ fun EditTaskSheet( text = category.ifBlank { "None" }, onClick = { categoryMenuOpen = true }, contentDescription = "Category: ${category.ifBlank { "none" }}. Change category", - container = MaterialTheme.colorScheme.secondaryContainer, - content = MaterialTheme.colorScheme.onSecondaryContainer, + container = badgeSwatch?.tintColor() ?: MaterialTheme.colorScheme.secondaryContainer, + content = badgeSwatch?.textColor() ?: MaterialTheme.colorScheme.onSecondaryContainer, ) CategoryMenu( expanded = categoryMenuOpen, diff --git a/app/src/main/java/com/mapgie/dash/ui/components/TaskOverviewSheet.kt b/app/src/main/java/com/mapgie/dash/ui/components/TaskOverviewSheet.kt index 44411b7..622ff72 100644 --- a/app/src/main/java/com/mapgie/dash/ui/components/TaskOverviewSheet.kt +++ b/app/src/main/java/com/mapgie/dash/ui/components/TaskOverviewSheet.kt @@ -36,6 +36,7 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.mapgie.dash.data.model.ReminderDto +import com.mapgie.dash.data.model.Swatch import com.mapgie.dash.data.model.TaskDto import com.mapgie.dash.data.model.TaskPriority import com.mapgie.dash.data.model.TaskUrgency @@ -60,6 +61,7 @@ import com.mapgie.dash.ui.theme.StatusTone import com.mapgie.dash.ui.theme.badgeContainerColor import com.mapgie.dash.ui.theme.statusTone import com.mapgie.dash.ui.theme.textColor +import com.mapgie.dash.ui.theme.tintColor import com.mapgie.dash.util.CalendarShareUtils import com.mapgie.dash.util.calendarEventForDate import com.mapgie.dash.util.calendarEventForInstant @@ -84,6 +86,10 @@ import java.time.temporal.ChronoUnit fun TaskOverviewSheet( task: TaskDto, icon: ImageVector, + /** Category colour for the due badge (Settings › Colours spine+badge axis), or null to follow urgency. */ + badgeSwatch: Swatch?, + /** Category colour for the icon chip (icon axis), or null to follow urgency. */ + iconSwatch: Swatch?, isPinned: Boolean, sheetState: SheetState, reminders: List = emptyList(), @@ -117,9 +123,13 @@ fun TaskOverviewSheet( sheetScope.launch { sheetState.hide() }.invokeOnCompletion { action() } } + // Same resolution as TaskCard: the Settings › Colours icon axis wins, else + // the urgency tone, else the plain task accent. val signalling = tone != StatusTone.NEUTRAL && tone != StatusTone.NONE - val chipContainer = if (signalling) tone.badgeContainerColor()!! else accents.taskContainer - val chipContent = if (signalling) tone.textColor() else accents.onTaskContainer + val chipContainer = iconSwatch?.tintColor() + ?: if (signalling) tone.badgeContainerColor()!! else accents.taskContainer + val chipContent = iconSwatch?.textColor() + ?: if (signalling) tone.textColor() else accents.onTaskContainer ModalBottomSheet( onDismissRequest = { hideAndDismiss() }, @@ -157,7 +167,17 @@ fun TaskOverviewSheet( horizontalArrangement = Arrangement.spacedBy(8.dp), modifier = Modifier.padding(top = 8.dp), ) { - dueBadgeText(task)?.let { StatusBadge(text = it, tone = if (isDone) StatusTone.NEUTRAL else tone) } + dueBadgeText(task)?.let { text -> + // The badge follows the spine+badge axis like the card's; a done + // task's badge stays neutral so the sheet matches the muted card. + val swatch = badgeSwatch?.takeIf { !isDone } + StatusBadge( + text = text, + tone = if (isDone) StatusTone.NEUTRAL else tone, + containerOverride = swatch?.tintColor(), + textOverride = if (swatch != null) MaterialTheme.colorScheme.onSurfaceVariant else null, + ) + } Text( text = metaText(task), style = MaterialTheme.typography.labelSmall.copy(fontSize = 13.sp, fontWeight = FontWeight.Bold), diff --git a/app/src/main/java/com/mapgie/dash/ui/screens/tasks/TaskListScreen.kt b/app/src/main/java/com/mapgie/dash/ui/screens/tasks/TaskListScreen.kt index efec0fd..fc10429 100644 --- a/app/src/main/java/com/mapgie/dash/ui/screens/tasks/TaskListScreen.kt +++ b/app/src/main/java/com/mapgie/dash/ui/screens/tasks/TaskListScreen.kt @@ -513,6 +513,8 @@ fun TaskListScreen( EditTaskSheet( task = editingTask, icon = editingTask?.let { iconFor(it) } ?: LucideIcons.CircleCheck, + badgeSwatch = editingTask?.let { uiState.spineSwatchFor(it) }, + iconSwatch = editingTask?.let { uiState.iconSwatchFor(it) }, owners = uiState.owners, categories = uiState.categories, onSave = { insert -> viewModel.addTask(insert) }, @@ -530,6 +532,8 @@ fun TaskListScreen( TaskOverviewSheet( task = task, icon = iconFor(task), + badgeSwatch = uiState.spineSwatchFor(task), + iconSwatch = uiState.iconSwatchFor(task), isPinned = task.id == uiState.pinnedTaskId, sheetState = overviewSheetState, reminders = uiState.reminders diff --git a/changelog/unreleased/task-sheet-colour-axes.json b/changelog/unreleased/task-sheet-colour-axes.json new file mode 100644 index 0000000..a96fcb5 --- /dev/null +++ b/changelog/unreleased/task-sheet-colour-axes.json @@ -0,0 +1,6 @@ +{ + "bump": "patch", + "fixed": [ + "Opening or editing a task now colours the sheet's icon chip, due badge and category chip by the Settings > Colours axes, matching the task card and the chore sheets." + ] +}