Skip to content

Notion checkboxes, double-click open, icon-picker polish, updater timeouts#14

Merged
resure merged 9 commits into
mainfrom
notion-checkboxes
Jul 6, 2026
Merged

Notion checkboxes, double-click open, icon-picker polish, updater timeouts#14
resure merged 9 commits into
mainfrom
notion-checkboxes

Conversation

@resure

@resure resure commented Jul 6, 2026

Copy link
Copy Markdown
Owner

Four user-facing improvements plus fixes and doc updates.

Features

Notion-style checkboxes (editor + read-only preview)

  • Custom-drawn rounded checkbox (appearance: none) that fills with the app accent and shows a white check when ticked; subtle border unticked, accent-tinted hover in the editor.
  • Box centered on the text line via calc((1lh - 17px)/2) (neutralizing the plugins' positioned top); tighter rows (6px) and text gap (7px).
  • Enabled @diplodoc/transform's checkbox plugin in the preview — it wasn't in the default set, so - [ ]/[x] leaked through as literal text. The WYSIWYG editor already uses the same plugin, so this fixes a pre-existing editor↔preview divergence (both now render task-token lines identically).

Double-click a note row to open it in its own window (desktop) — reuses the conflict-checked open-in-new-window path, matching ⌘↵ / ⌘-click / the ⋯ menu.

Icon-picker polish (three backlog items)

  • aria-activedescendant no longer dangles at a virtualized-out option — a rangeExtractor force-mounts the keyboard-highlighted row.
  • The note-title picker can no longer set an icon in read-only preview mode — the popup closes when the picker becomes disabled (plus an onSetIcon guard).
  • Debounced icon search (100ms) so filtering thousands of icons/emoji doesn't re-run on every keystroke.

Updater timeouts — the manifest check() (15s) and the binary download (120s, for the ~6MB artifact) are now bounded, so a stalled connection can't hang "Checking for updates…" / a 0-B download forever (which also latched busyRef, blocking retries).

Fixes

  • Icon-picker crash (found in self-review): the rangeExtractor could push a row index past a shrunken result set → the virtualizer yielded an undefined item → render crash on virtualRow.key. Guarded with activeRow < rows.length; regression test verified to crash without the guard.
  • Checkbox label text raised 1px to its natural baseline (editor + preview kept in parity).

Docs / tooling

  • Proposal doc for the "preserve ⌘Z across note switches" backlog item (design only, not implemented).
  • Release skill now sources signing creds from ~/.localrc (fresh-shell-per-call, zsh-portable check).
  • docs/shortcuts.md + README backlog updates; .claude/launch.json preview server moved off port 5173 so it doesn't collide with tauri dev.

Verification

  • 930 tests pass (added IconPicker, double-click, and updater-timeout tests); typecheck, lint, and format clean.
  • Checkboxes, icon picker, and double-click verified live in the browser preview across light/dark.

🤖 Generated with Claude Code

resure and others added 9 commits July 6, 2026 22:05
Checkboxes (editor + read-only preview):
- Custom-drawn rounded square (appearance:none) with accent fill + white
  check when ticked; subtle border unticked, accent-tint hover in editor.
  Follows the app accent and adapts to light/dark.
- Center the box on the line via calc((1lh - 17px)/2), neutralizing the
  plugins' positioned `top` shift; nudge the label text 1px down so it
  optically seats on the box. Tighter rows (6px) and text gap (7px).
- Enable @diplodoc/transform's checkbox plugin in the preview — it wasn't
  in the default set, so `[ ]`/`[x]` leaked through as literal text; the
  WYSIWYG editor already uses the same plugin, so this restores parity.

NoteList: double-click a row opens the note in its own window (desktop),
reusing the conflict-checked open-in-new-window path (+ tests).

useAppUpdater: pass a 15s timeout to the updater check() so a stalled
manifest fetch can't hang "Checking for updates…" (and latch busyRef)
forever. Deliberately no download timeout — the plugin maps it to
reqwest's whole-request timeout, which would abort slow large downloads.

Docs: note double-click in shortcuts.md; drop the done "Better looking
checklists" backlog item.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The check() timeout fixed the "Checking for updates…" hang, but the
binary download still had none — so a stall at 0 B hung "Updating…"
forever (and latched busyRef, blocking retry). Pass a 120s timeout to
downloadAndInstall. The artifact is only ~6 MB, so 2 min clears it on
any usable link while still bailing out of a true stall — the earlier
worry about aborting slow "multi-MB" downloads doesn't apply at 6 MB.

Add tests asserting both check() and downloadAndInstall() receive their
timeouts.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Three backlog fixes for the icon picker:

- aria-activedescendant no longer dangles: add a rangeExtractor (mirroring
  NoteList) that force-mounts the keyboard-highlighted grid row, so the
  search box's aria-activedescendant always references a live element even
  when the option is scrolled out of the virtual window.

- Read-only preview mode: the note-title picker's disabled button already
  blocks opening, but toggling into preview (⌘⇧P) with the popup open left
  it pickable. Close the popup when the picker becomes disabled, and guard
  onSetIcon in NoteTitle as defense-in-depth.

- Debounce the search query (100ms) that drives filtering — the catalog is
  thousands of icons + emoji, so re-filtering and re-virtualizing on every
  keystroke was wasteful. The input stays bound to the live value for
  responsive typing; only the grid reads the settled query.

Add IconPicker.test.tsx covering all three.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A design proposal (not yet implemented) for the "Preserve cmd+z between
notes" backlog item: hold each note's live ProseMirror/CodeMirror
EditorState and restore it on switch-back (history rides with the state
object), keyed per active mode, LRU-capped, with a content-match guard
that falls back to today's fresh reset. Contained to EditorPane's swap
logic.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Review caught the editor's checklist label rule at top: 0px while its
comment (and the preview's .checkbox > label rule) say 1px — the editor
and read-only preview rendered the label at different heights, breaking
the editor↔preview parity invariant. Set it to 1px so the label seats on
the box in both surfaces. Verified live (label top: 1px, box centered on
the line). Also reflow the undo-preservation proposal doc to Prettier.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- IconPicker: guard the rangeExtractor with `activeRow < rows.length`.
  Roving the highlight down then filtering to a smaller (non-empty) set
  left activeRow past the shrunken list for one render (the reset is a
  post-commit effect); pushing that out-of-range index handed the
  virtualizer an undefined item and crashed the render on virtualRow.key.
  Add a regression test that roves then shrinks the grid (verified it
  crashes without the guard).

- Checkboxes: drop the 1px label nudge in both editor and preview so the
  label text sits 1px higher, at its natural baseline (kept in parity).

- .claude/launch.json: run the web preview on port 5273 (--strictPort) so
  it never collides with `tauri dev`'s vite on 5173 (the collision was
  killing the desktop dev server's HMR).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The Apple + updater signing vars live in ~/.localrc, and the Bash tool
starts a fresh shell each call (env doesn't persist), so the preflight
check and the build step must each `source ~/.localrc` in the same
command. Add the sourcing to Step 0 and Step 3, plus a portable
(non-bash `${!v}`) credential-presence check, since the tool runs zsh.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Pre-existing drift (unrelated to this branch) — current stable rustfmt
wants a few cosmetic line-wraps; `cargo fmt --check` was already red on
main. Whitespace only, no logic change. Fixes the `rust` CI job.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The icon-picker interaction tests (userEvent through a virtualized grid)
are heavy; under CI worker contention a boundary-slow NoteList test hit
~16s and timed out at the 15s limit. Bump the DOM suite timeout to 30s
and drop the now-redundant per-test override.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@resure resure merged commit f2a4c56 into main Jul 6, 2026
2 checks passed
@resure resure deleted the notion-checkboxes branch July 6, 2026 21:12
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