Skip to content

Simplify our TODO system and improve its dialog#26

Merged
nedtwigg merged 23 commits intomainfrom
todo-simplify
Apr 24, 2026
Merged

Simplify our TODO system and improve its dialog#26
nedtwigg merged 23 commits intomainfrom
todo-simplify

Conversation

@nedtwigg
Copy link
Copy Markdown
Member

  • get rid of "soft" TODO
  • TODO is only auto-dismissed by hitting enter
  • improve the alarm right-click dialog

nedtwigg and others added 23 commits April 23, 2026 18:10
Drops the off/soft/hard trichotomy and its bucket/recovery/strike
machinery. A TODO is now either on or off. Clicking the pill dismisses
it (reuses the existing ✓ flourish), and pressing Enter in passthrough
also clears it — the user confirming an action is the reminder being
done. Attending or dismissing a ringing alert turns TODO on.

The right-click popup drops the hard/off buttons for a simpler
[on] [off] radio pair on both TODO and alert rows, with updated help
text describing the new Enter-clears behavior.

Persisted schema bumps v2 → v3: PersistedAlertState.todo becomes
boolean. migrateSessionV2toV3 maps any non-(-1) numeric encoding to
true; v1 blobs chain through v2 to v3.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Hot area = the dialog itself ∪ a trapezoid connecting the top
corners of the bell button to the top corners of the dialog, so
the cursor can travel from button to dialog without dismissing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…its.

- Dismiss animation: one continuous motion — letters fade out while a
  ✓ springs in, brief hold, then the pill shell dissolves out together.
  Unifies the pill DOM across steady/flourishing states so there is
  no element swap, no width reflow, and the border no longer
  disappears abruptly at the end.
- Popup dialog: stabilize `onClose` with `useCallback` so the
  focus-trap effect does not clean up on every parent re-render and
  restore focus to the bell button, which was bailing out subsequent
  `a`/`t` presses.
- Split buttons: rename "Split horizontal" → "Split left/right" and
  "Split vertical" → "Split top/bottom" in UI, specs, and tutorial
  (and fix the matching shortcut hints in layout.md).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ond.tsx.

Pond.tsx goes from 2334 to 1820 lines. The three extracted pieces are
self-contained widgets with clear boundaries:

- HeaderActionButton.tsx (105 lines): generic icon-button + hover
  tooltip.
- TodoAlertDialog.tsx (241 lines): the popup, its OnOffSwitch, the
  popover focus-trap hook, and a point-in-convex-polygon helper.
  Exposes isDialogKeyboardActive() so Pond's command-mode handler
  can bail while the dialog owns a/t.
- KillConfirm.tsx (195 lines): KillConfirmCard, KillConfirmOverlay,
  orchestrateKill, randomKillChar, and the ConfirmKill type.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The x/y fields were always derived from triggerRect (rect.left and
rect.bottom + 8), so carrying them as separate fields just duplicated
state. Drop them and compute the dialog's top-left inside the dialog.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
onFocus/onBlur were present in the original in-Pond definition but
got dropped during the extraction to its own file, so keyboard-tab
navigation stopped triggering header tooltips.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The extraction from Pond dropped the clampOverlayPosition wrapper, so
a dialog triggered from a bell near the right edge of the window would
overflow off-screen. Measure the mounted dialog with useLayoutEffect and
apply margin-based clamping before the browser paints.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The dialog can also be opened by keyboard (pressing 'a' on a ringing
pane). Previously, the mousemove handler closed the dialog on the first
move if the cursor was already outside the hot area at open time, making
the dialog unusable with the keyboard unless the cursor happened to be
parked near the bell. Now the close-on-leave trigger only arms once the
cursor has actually entered the dialog or its funnel.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The flag that tells Pond's keyboard handler to stand down while
TodoAlertDialog is open was a module-level mutable variable with an
exported accessor — implicit coupling that would silently break with
multiple simultaneous dialogs.

Replace it with DialogKeyboardContext: Pond owns a ref and provides a
setter via context; TerminalPaneHeader reads the context and threads it
into TodoAlertDialog as an onKeyboardActiveChange prop.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…irectly

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@nedtwigg nedtwigg merged commit c58951a into main Apr 24, 2026
6 checks passed
@nedtwigg nedtwigg deleted the todo-simplify branch April 24, 2026 17:36
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