Skip to content

Show the read-time chip only once the visible text is measured - #24

Merged
sjmiller609 merged 1 commit into
mainfrom
hypeship/read-time-client-only
Jul 31, 2026
Merged

Show the read-time chip only once the visible text is measured#24
sjmiller609 merged 1 commit into
mainfrom
hypeship/read-time-client-only

Conversation

@sjmiller609

@sjmiller609 sjmiller609 commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Follow-up to #23. The bar was painting a server-side estimate over the whole stored HTML and then swapping in the overlay's visible-text number — so a doc with hidden tab panels showed a figure we already knew was wrong, then corrected itself. Now nothing shows until the client has measured.

What changed

  • No server estimate. estimateReadMinutes(html) and its call in app/d/[slug]/page.tsx are gone, along with the readMinutes prop. Counting the stored HTML can only ever produce the number we didn't want.
  • The overlay posts raw counts{type:"jh:readtime", words, cjk} instead of minutes. The rate, the rounding and the thresholds stay in lib/docs/reading-time.ts as readMinutesFor(words, cjk), which the shell calls: one tested definition of the arithmetic instead of the constants being duplicated into the stringified overlay script.
  • The chip renders only when a report arrives. readMinutes starts null; a doc whose overlay never runs has no chip at all, and an image-only doc still reports 0 and stays chipless.
  • Reporting waits for the doc to settle. Read time no longer rides the theme sample's load/400ms ticks — measured that early, a script-built tab UI still has every panel visible, so we'd show a number and correct it a second later (the old behaviour did exactly this: 24 min at 700ms, 4 min at 1.5s). It now reports at 1.5s and again at 5s for a doc that rearranges itself very late; an unchanged count is a no-op for the shell.

Trade-off: the chip appears about 1.5s in rather than immediately, and the other bar controls shift left when it does. That seemed the right side of "don't show a number we'd have to take back".

Testing

  • npm test — 170 passing. The estimator's HTML-scraping tests are replaced by tests for readMinutesFor (wpm rounding, CJK rate, mixed docs, the zero case); thresholds and tooltip copy unchanged.
  • npm run build and tsc --noEmit clean.
  • Verified in a browser over CDP against seeded fixtures: server HTML contains no chip at all; at 700ms every fixture shows no chip; by 2.5s the 600/1600/4000-word docs read 4 min green, 9 min beige, 21 min charcoal, a CSS-tabbed doc 4 min, a script-tabbed doc that hides panels at 1s 4 min, 4000 words in a closed <details> 3 min, and an image-only doc still has no chip. No intermediate wrong number in any of them. Light and dark both checked.
  • The overlay half remains fixture-verified by hand — stringified browser JS, no unit-test harness.

Note

Low Risk
Viewer chrome timing and display only; no auth, persistence, or API contract changes beyond the overlay postMessage shape paired with the shell update.

Overview
Stops showing a read-time chip from server HTML and waits for the sandbox overlay to measure visible prose only, so tab panels and other hidden content no longer produce a number that flashes wrong and then corrects.

The viewer page drops estimateReadMinutes and the readMinutes prop. CommentsShell keeps readMinutes as null until jh:readtime arrives; zero or missing overlay means no chip. The overlay posts {words, cjk} instead of minutes; readMinutesFor in lib/docs/reading-time.ts owns rates and rounding. Reporting moves off theme load/400ms ticks to 1.5s and 5s so late tab UIs can settle first. Tests target readMinutesFor rather than HTML scraping.

Reviewed by Cursor Bugbot for commit 82d9b45. Bugbot is set up for automated code reviews on this repo. Configure here.

The bar used to paint a server-side estimate over the whole stored HTML and then
swap in the overlay's visible-text number, so a doc with hidden tab panels
showed a figure we already knew was wrong. There is now no server estimate: the
overlay posts word/CJK counts for the text it finds visible, the shell turns
those into minutes, and no chip renders until that arrives.

The overlay also stops reporting on the theme sample's early ticks — a count
taken before a script-built tab UI hides its panels would put up a number that
then has to be corrected. It reports once the doc has settled and once more
later for a doc that rearranges itself very late.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 31, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
justhtml Ready Ready Preview Jul 31, 2026 3:55pm

@sjmiller609
sjmiller609 marked this pull request as ready for review July 31, 2026 15:55
@sjmiller609
sjmiller609 merged commit 5713fe7 into main Jul 31, 2026
5 checks passed
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