Skip to content

feat(task-expand): 1s yellow flash on expand:N target (visible feedback) - #684

Merged
sonichi merged 1 commit into
mainfrom
feat/task-expand-flash
May 14, 2026
Merged

sonichi merged 1 commit into
mainfrom
feat/task-expand-flash

Conversation

@sonichi

@sonichi sonichi commented May 14, 2026

Copy link
Copy Markdown
Owner

Summary

Voice "expand task N" was confusing — when the target task already auto-expanded, or had no result body, expand:N produced no visible change. Hard to know which task got expanded after index-shift.

Adds a 1s yellow background flash on every DOM element with data-taskid="<targetId>" (covers both render paths — primary #tasks AND dynamic-region #dr-content). Always-visible confirmation that the expand landed.

How

  • CSS: new @keyframes task-flash-anim + .task-item.task-flash { animation: ... 1s ease-out }.
  • JS: in the expand:N branch of the MutationObserver, after renderTasks(), query all [data-taskid="<targetId>"] elements and toggle the .task-flash class. Force reflow (void el.offsetWidth) so repeated expand:N on the same task re-fires the animation.

Test plan

  • tsc clean
  • voice "expand task 3" → task 3's row briefly flashes yellow, then fades
  • repeat "expand task 3" → flashes again (no need to wait for class to expire)
  • bare "expand" / "collapse" (no index) unchanged

🤖 Generated with Claude Code

…dback

Per Chi 2026-05-14 02:55 PT: voice "expand task N" was confusing
because — even when the target task DID land in expandedTasks — the
visible effect depended on whether the task had a result body. New
tasks without results showed no change. Plus index-shift between voice
utterance and command dispatch made it unclear which task got the
expand.

Adds a 1s background-color flash (rgba(255, 220, 100, 0.45) →
transparent) on every DOM element with `data-taskid="<targetId>"`
when expand:N successfully resolves. Both render paths (primary
renderTasks at #tasks AND dynamic-region at #dr-content) get the
class. Force reflow on re-trigger so repeat expand:N still flashes.

50ms delay before applying lets renderTasks() paint the post-add
DOM first.
@sonichi
sonichi merged commit 187a2b6 into main May 14, 2026
1 check passed
@sonichi
sonichi deleted the feat/task-expand-flash branch May 14, 2026 02:59
sonichi added a commit that referenced this pull request May 14, 2026
…and:N hit working tasks (#686)

Both renderers (primary line 1150, dynamic-region line 2319) only attached
`data-taskid` when `hasResult` was true. For working tasks (no result yet),
the wrapper had no data-taskid — so:

- the 1s yellow flash from PR #684 silently no-op'd (querySelectorAll
  `[data-taskid="..."]` matched nothing)
- the `.expanded` class still got added to .task-text, but that only widens
  long titles via `white-space: normal`; short titles looked unchanged

Fix:
- Always emit `data-taskid` on the .task-item wrapper, in both renderers.
- Add `data-clickable="1"` (only when hasResult) as the separate flag the
  global click handler uses — preserves "working tasks aren't clickable"
  behavior without coupling it to the flash target.

Self-verified via Chrome MCP:
- 30/30 .task-item have data-taskid
- expand:3 → target's .task-text gets .expanded AND .task-flash applied
- Click handler still only fires for clickable items.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
liususan091219 pushed a commit to liususan091219/sutando-fork that referenced this pull request May 28, 2026
…dback (sonichi#684)

Per Chi 2026-05-14 02:55 PT: voice "expand task N" was confusing
because — even when the target task DID land in expandedTasks — the
visible effect depended on whether the task had a result body. New
tasks without results showed no change. Plus index-shift between voice
utterance and command dispatch made it unclear which task got the
expand.

Adds a 1s background-color flash (rgba(255, 220, 100, 0.45) →
transparent) on every DOM element with `data-taskid="<targetId>"`
when expand:N successfully resolves. Both render paths (primary
renderTasks at #tasks AND dynamic-region at #dr-content) get the
class. Force reflow on re-trigger so repeat expand:N still flashes.

50ms delay before applying lets renderTasks() paint the post-add
DOM first.
liususan091219 pushed a commit to liususan091219/sutando-fork that referenced this pull request May 28, 2026
…and:N hit working tasks (sonichi#686)

Both renderers (primary line 1150, dynamic-region line 2319) only attached
`data-taskid` when `hasResult` was true. For working tasks (no result yet),
the wrapper had no data-taskid — so:

- the 1s yellow flash from PR sonichi#684 silently no-op'd (querySelectorAll
  `[data-taskid="..."]` matched nothing)
- the `.expanded` class still got added to .task-text, but that only widens
  long titles via `white-space: normal`; short titles looked unchanged

Fix:
- Always emit `data-taskid` on the .task-item wrapper, in both renderers.
- Add `data-clickable="1"` (only when hasResult) as the separate flag the
  global click handler uses — preserves "working tasks aren't clickable"
  behavior without coupling it to the flash target.

Self-verified via Chrome MCP:
- 30/30 .task-item have data-taskid
- expand:3 → target's .task-text gets .expanded AND .task-flash applied
- Click handler still only fires for clickable items.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant