From 168a6433082322b8791dc5f3b0f41c5ddb5f7125 Mon Sep 17 00:00:00 2001 From: badcuban <108198679+badcuban@users.noreply.github.com> Date: Thu, 3 Sep 2026 01:45:57 -0400 Subject: [PATCH 1/2] feat(web): task list in the activity popover sits on a spine The task rows in the header activity popover were filled grey, blue, and green boxes with struck-through text, which reads badly on phone and desktop and fights the flat design rule. Render the steps as rows on the shared thread spine instead: a quiet dot for done steps, the pulsing accent tick for the current one with the line warming toward it, and a faint hollow ring for steps not started. The Done/Now/Next column is gone (kept for screen readers) and completed text is dimmed, not struck through. SpineNode moves from MessagesTimeline into ui/threadline so both surfaces share one dot. --- .../src/components/chat/MessagesTimeline.tsx | 46 +----------- .../components/chat/ThreadActivityPopover.tsx | 73 +++++++++---------- apps/web/src/components/ui/threadline.tsx | 54 +++++++++++++- 3 files changed, 90 insertions(+), 83 deletions(-) diff --git a/apps/web/src/components/chat/MessagesTimeline.tsx b/apps/web/src/components/chat/MessagesTimeline.tsx index 371f39170..397b8b2e5 100644 --- a/apps/web/src/components/chat/MessagesTimeline.tsx +++ b/apps/web/src/components/chat/MessagesTimeline.tsx @@ -81,7 +81,7 @@ import { import { Button } from "../ui/button"; import { Popover, PopoverPopup, PopoverTrigger } from "../ui/popover"; import { Textarea } from "../ui/textarea"; -import { SpineRow, spineAccentRowStyle } from "../ui/threadline"; +import { SpineNode, SpineRow, spineAccentRowStyle, type SpineNodeKind } from "../ui/threadline"; import { buildExpandedImagePreview, ExpandedImagePreview } from "./ExpandedImagePreview"; import type { FilePreviewRequest } from "./FilePreviewDialog"; import { loadChatAttachmentBlob } from "../../lib/attachmentPreviewQuery"; @@ -2678,48 +2678,6 @@ function LiveMessageMeta({ // re-render only the affected row, not the entire list. // --------------------------------------------------------------------------- -/** Owns its own expand/collapse state so toggling re-renders only this row. - * State resets on unmount which is fine — work groups start collapsed. */ -type SpineNodeKind = "done" | "running" | "warning" | "error" | "group"; - -const TONE_SPINE_DOT_CLASS_NAME = { - warning: "size-[6px] rounded-full bg-warning", - error: "size-[6px] rounded-full bg-destructive", -} as const satisfies Record<"warning" | "error", string>; - -/** The glyph that sits on the activity spine for one row. The accent halo is - * reserved for the turn's working row below the timeline tail; a still-running - * step gets a small accent tick, settled steps are quiet solid dots, - * warnings/errors are compact tone dots, and a collapsed group of steps is a - * hollow ring (same family, reads as "openable"). */ -function SpineNode({ kind }: { kind: SpineNodeKind }) { - if (kind === "running") { - return ( -