summaryrefslogtreecommitdiff
path: root/android
diff options
context:
space:
mode:
authorPeter Stone <thepeterstone@gmail.com>2026-08-12 07:57:51 +0000
committerPeter Stone <thepeterstone@gmail.com>2026-08-12 07:57:51 +0000
commit3e8ad60431d6cc783f9f7c555bfde5db54ebec75 (patch)
treecb7dfc1e22cf472e087c62cbcaa452c1525c7aa0 /android
parent9a3ece4fef431c2c35af239f3df6eeaa10ddeaf4 (diff)
Fix tomorrow's task rows: color and alignment vs tomorrow's events
TaskRow always used textPrimary for its title, while tomorrow's timed events (TimeLabeledEventRow) are deliberately de-emphasized with textSecondary -- tomorrow's tasks now match. TaskRow also had no leading gutter of its own outside the hourly grid (where HourRow's hour-label column supplies it externally), so in TomorrowSection its title landed at a variable offset depending on checkbox/dot size and hideCheckboxes, instead of the fixed 32dp gutter AllDayRow and TimeLabeledEventRow use there. Added optional titleColor/gutterWidth params to TaskRow (both default to prior grid behavior) and set them from TomorrowSection. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017GMEkHeqKz6FLkmizowBTK
Diffstat (limited to 'android')
-rw-r--r--android/app/src/main/java/org/terst/doot/widget/ui/WidgetRows.kt105
1 files changed, 74 insertions, 31 deletions
diff --git a/android/app/src/main/java/org/terst/doot/widget/ui/WidgetRows.kt b/android/app/src/main/java/org/terst/doot/widget/ui/WidgetRows.kt
index 8ac1f91..a5e9d26 100644
--- a/android/app/src/main/java/org/terst/doot/widget/ui/WidgetRows.kt
+++ b/android/app/src/main/java/org/terst/doot/widget/ui/WidgetRows.kt
@@ -4,6 +4,7 @@ import android.content.Intent
import android.net.Uri
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.glance.*
import androidx.glance.action.actionParametersOf
@@ -300,7 +301,20 @@ fun TaskFragmentBlock(fragment: TaskFragment, textSize: WidgetTextSize, palette:
}
@Composable
-fun TaskRow(task: WidgetItem, textSize: WidgetTextSize, palette: WidgetPalette, hideCheckboxes: Boolean = false) {
+fun TaskRow(
+ task: WidgetItem,
+ textSize: WidgetTextSize,
+ palette: WidgetPalette,
+ hideCheckboxes: Boolean = false,
+ titleColor: Color = palette.textPrimary,
+ // Null (default) preserves the grid's existing behavior, where HourRow's own
+ // hour-label column already supplies the 32dp gutter externally and this row
+ // starts flush at the Column edge. TomorrowSection passes 32.dp so its task
+ // rows reserve the same leading width as AllDayRow's Spacer(32.dp) and
+ // TimeLabeledEventRow's width(32.dp) time label, keeping titles aligned with
+ // tomorrow's events regardless of hideCheckboxes/completable/dot sizing.
+ gutterWidth: Dp? = null
+) {
val context = LocalContext.current
val detailIntent = Intent(context, TaskDetailActivity::class.java).apply {
putExtra(TaskDetailActivity.EXTRA_ID, task.id)
@@ -316,7 +330,12 @@ fun TaskRow(task: WidgetItem, textSize: WidgetTextSize, palette: WidgetPalette,
Row(
modifier = GlanceModifier
.fillMaxWidth()
- .padding(horizontal = 8.dp, vertical = 5.dp),
+ .padding(
+ start = if (gutterWidth != null) 0.dp else 8.dp,
+ end = 8.dp,
+ top = 5.dp,
+ bottom = 5.dp
+ ),
verticalAlignment = Alignment.CenterVertically
) {
// Suppressing checkboxes drops this leading element entirely rather than just
@@ -325,36 +344,50 @@ fun TaskRow(task: WidgetItem, textSize: WidgetTextSize, palette: WidgetPalette,
// task titles land flush with event titles instead of offset by unused space.
// Tradeoff: tap-to-complete-from-the-widget goes with it (TaskDetailActivity's
// Complete button still works), which is what "so everything lines up" implies.
- if (!hideCheckboxes) {
- if (task.completable) {
- Box(
- modifier = GlanceModifier
- .size(24.dp)
- .clickable(
- actionRunCallback<CompleteTaskAction>(
- actionParametersOf(
- CompleteTaskAction.idKey to task.id,
- CompleteTaskAction.sourceKey to task.source
+ //
+ // When gutterWidth is set (TomorrowSection), that reasoning doesn't apply --
+ // the row it's aligning against (TimeLabeledEventRow) always reserves a fixed
+ // 32dp leading width whether or not there's a visible label there, so this
+ // leading slot is reserved too, checkboxes shown or not.
+ val leadingContent: @Composable () -> Unit = {
+ if (!hideCheckboxes) {
+ if (task.completable) {
+ Box(
+ modifier = GlanceModifier
+ .size(24.dp)
+ .clickable(
+ actionRunCallback<CompleteTaskAction>(
+ actionParametersOf(
+ CompleteTaskAction.idKey to task.id,
+ CompleteTaskAction.sourceKey to task.source
+ )
)
- )
- ),
- contentAlignment = Alignment.Center
- ) {
- Image(
- provider = ImageProvider(org.terst.doot.widget.R.drawable.ic_checkbox_empty),
- contentDescription = "Complete ${task.title}",
- colorFilter = ColorFilter.tint(ColorProvider(palette.textSecondary)),
- modifier = GlanceModifier.size(14.dp)
- )
+ ),
+ contentAlignment = Alignment.Center
+ ) {
+ Image(
+ provider = ImageProvider(org.terst.doot.widget.R.drawable.ic_checkbox_empty),
+ contentDescription = "Complete ${task.title}",
+ colorFilter = ColorFilter.tint(ColorProvider(palette.textSecondary)),
+ modifier = GlanceModifier.size(14.dp)
+ )
+ }
+ } else {
+ Box(
+ modifier = GlanceModifier
+ .size(8.dp)
+ .background(palette.textMuted)
+ ) {}
}
- } else {
- Box(
- modifier = GlanceModifier
- .size(8.dp)
- .background(palette.textMuted)
- ) {}
}
}
+ if (gutterWidth != null) {
+ Box(modifier = GlanceModifier.width(gutterWidth), contentAlignment = Alignment.CenterStart) {
+ leadingContent()
+ }
+ } else {
+ leadingContent()
+ }
if (task.projectColor != null) {
Box(
@@ -375,7 +408,7 @@ fun TaskRow(task: WidgetItem, textSize: WidgetTextSize, palette: WidgetPalette,
ShadowedText(
text = task.title,
style = TextStyle(
- color = ColorProvider(palette.textPrimary),
+ color = ColorProvider(titleColor),
fontSize = textSize.scaledContentSize(14),
fontWeight = textSize.scaledContentWeight(FontWeight.Normal)
),
@@ -457,12 +490,22 @@ fun TomorrowSection(
if (item.type == "event") {
TimeLabeledEventRow(item, zone, textSize, palette, titleColor = palette.textSecondary)
} else {
- TaskRow(item, textSize, palette, hideCheckboxes)
+ TaskRow(
+ item, textSize, palette, hideCheckboxes,
+ titleColor = palette.textSecondary,
+ gutterWidth = 32.dp
+ )
}
}
fragments.forEach { frag ->
- frag.slots.forEach { slot -> TaskRow(slot.task, textSize, palette, hideCheckboxes) }
+ frag.slots.forEach { slot ->
+ TaskRow(
+ slot.task, textSize, palette, hideCheckboxes,
+ titleColor = palette.textSecondary,
+ gutterWidth = 32.dp
+ )
+ }
}
}
}