Skip to content

fix: reply composer stays open on live arrivals + Show more light-mode contrast#17

Merged
DocNR merged 3 commits into
mainfrom
fix/reply-composer-stays-open
Jun 17, 2026
Merged

fix: reply composer stays open on live arrivals + Show more light-mode contrast#17
DocNR merged 3 commits into
mainfrom
fix/reply-composer-stays-open

Conversation

@DocNR

@DocNR DocNR commented Jun 17, 2026

Copy link
Copy Markdown
Owner

Two small light-touch bug fixes, both user-facing.

1. Reply composer closing on live arrivals (the main one)

Symptom: while replying to a note in a feed, the compose box would occasionally close on its own when new notes came in.

Root cause: the reply composer's open state lives in ReplyButton, which renders inside a virtua-virtualized NoteCard row, so the dialog only lives as long as its row stays mounted. When a live note arrived while the user was at/near the top of a feed, NoteList.handleNewEvents prepended it and forced scrollToTop('instant'), re-laying out the virtual list and jumping the scroll. The row owning the open dialog could fall out of virtua's render window and unmount, destroying its open state. The Radix modal blocks the user from scrolling the feed behind it, but not that programmatic scroll, so live arrivals were the one thing that could disturb the feed mid-compose. (Felt random because it only fires near the top; scrolled down, arrivals already buffer into the pill.)

Fix: track open composers app-wide via a refcount on post-editor.service (registered at the LazyPostEditor chokepoint that every composer funnels through, before the lazy chunk resolves). While any composer is open, NoteList buffers live arrivals into the existing "show new notes" pill instead of mutating/scrolling the rendered timeline, so the owning row stays mounted and the dialog stays open. The pill flushes when the composer closes. Bonus: also kills the feed lurching to the top under an open composer.

2. "Show more" button contrast in light mode

The Collapsible "Show more" button overrode its background to bg-foreground but kept the default Button variant's text-primary-foreground. Those tokens aren't a contrasting pair: in light mode both resolve to near-black, giving unreadable dark-on-dark text (dark mode happened to look fine because bg-foreground flips to near-white). Changed the text to text-background, the correct inverse, so it reads in both themes.

Tests / verification

  • New unit tests for the composer-open refcount + event boundary (post-editor.service.spec.ts, 5 cases, written first).
  • Full suite green (873 passed), tsc -b clean, npm run build (CI gate) passes.
  • The row-unmount behavior itself isn't unit-testable; manual check: open Home at the top, start a reply, let live notes arrive -> composer stays open, pill collects the new notes, no feed jump.

Includes release note + version bump to 26.15.1.

🤖 Generated with Claude Code

DocNR and others added 3 commits June 16, 2026 22:58
The reply composer's open state lives in ReplyButton, which renders
inside a virtua-virtualized NoteCard row. When a live note arrived while
the user was at/near the top of a feed, NoteList.handleNewEvents
prepended it and forced scrollToTop, re-laying out the virtual list and
jumping the scroll. The row owning the open dialog could fall out of
virtua's render window and unmount, destroying its open state and closing
the composer out from under the user. The Radix modal blocks user scroll
of the feed behind it but not this programmatic scroll, so live arrivals
were the one thing that could disturb the feed mid-compose.

Track open composers app-wide via a refcount on post-editor.service
(registered at the LazyPostEditor chokepoint, before the lazy chunk
resolves). While any composer is open, NoteList buffers live arrivals
into the existing "new notes" pill instead of mutating/scrolling the
rendered timeline, so the owning row stays mounted and the dialog stays
open. The pill flushes when the composer closes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The Collapsible "Show more" button overrode its background to
bg-foreground but kept the default Button variant's
text-primary-foreground. Those tokens aren't a contrasting pair: in light
mode both resolve to near-black (bg hsl(240 10% 3.9%), text
hsl(186 90% 8%)), giving unreadable dark-on-dark text. It only looked
fine in dark mode because bg-foreground flips to near-white there.

Set the text to text-background, the correct inverse of foreground, so
the inverted button reads in both themes (white text in light mode,
near-black text in dark mode).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying jank with  Cloudflare Pages  Cloudflare Pages

Latest commit: ccc8761
Status: ✅  Deploy successful!
Preview URL: https://3c291730.jank-4ii.pages.dev
Branch Preview URL: https://fix-reply-composer-stays-ope.jank-4ii.pages.dev

View logs

@DocNR
DocNR merged commit 3ccfd28 into main Jun 17, 2026
2 checks passed
@DocNR
DocNR deleted the fix/reply-composer-stays-open branch June 17, 2026 03:01
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