fix(desktop): stabilize channel-timeline scrollback with per-row height reserves#1413
Merged
Conversation
…ht reserves Scrolling back through channels with mixed message types (images, code, link previews, video thumbs) jumped hard: every row used a flat `content-visibility: auto 60px` placeholder, so never-painted rows snapped from 60px to true height as they realized on scroll-up, shoving the column. Two targeted fixes: - Per-row pre-paint height estimate (rowHeightEstimate.ts): reserve a credible contain-intrinsic-size per row from its content. Drift through a mixed-media scrollback drops ~20x (1538px flat-60 baseline -> ~66-96px). - Dim-less image reserve + decoded-size cache + lightbox fix (markdown): images without a NIP-92 dim reserve a stable box and cache decoded natural size by URL, so they decode into reserved space instead of popping the row. Tests: rowHeightEstimate unit coverage; timeline-no-shift mixed-media gate (bounded first-pass prepend drift, no-shift maxDrift 0). Known follow-up (pre-existing on main, not addressed here): abandoning an in-flight older-history fetch by jumping to latest can land slightly above the floor under load; needs an explicit bottom-intent/loader protocol. An earlier rendered-floor bottom-pin attempt regressed cold-load "start at bottom" and was reverted, so this change leaves the anchored-scroll path untouched from main. Co-authored-by: Brain <21994759fc7a6fa6b965551d35cfd7897d262f2495467f2d78694ddcfa6a5c7e@sprout-oss.stage.blox.sqprod.co> Co-authored-by: Pinky <44b8e82baa6e0e254e0208d68f335c283c94e7b78dd1fa10d5a49d3f13dd0435@sprout-oss.stage.blox.sqprod.co> Signed-off-by: Wes <wesbillman@users.noreply.github.com>
tellaho
pushed a commit
that referenced
this pull request
Jul 1, 2026
…-preview * origin/main: fix(relay): enable Redis TLS for rediss:// (ElastiCache) (#1417) chore(release): release Buzz Desktop version 0.3.40 (#1414) fix(desktop): stabilize channel-timeline scrollback with per-row height reserves (#1413) fix(sidebar): trim working badge label and name working agents in tooltip (#1408) Mobile tab bar polish (#1368) feat(desktop): let thread pane expand on ultrawide monitors (#1407) chore(release): release Buzz Desktop version 0.3.39 (#1410) fix: close cross-process keychain race and namespace dev-build nest (#1409) feat(relay): allow agent owners to edit/manage agent-owned content (#1403) fix(media): support IRSA/credential-chain S3 auth and configurable signing region (#1406) fix(desktop): fold baked build env into in-process model discovery (#1376) docs: link VISION_ACTIVITY from the VISION index (#1405)
tellaho
pushed a commit
that referenced
this pull request
Jul 1, 2026
…vity-embed * origin/main: fix(relay): enable Redis TLS for rediss:// (ElastiCache) (#1417) chore(release): release Buzz Desktop version 0.3.40 (#1414) fix(desktop): stabilize channel-timeline scrollback with per-row height reserves (#1413) fix(sidebar): trim working badge label and name working agents in tooltip (#1408) Mobile tab bar polish (#1368) feat(desktop): let thread pane expand on ultrawide monitors (#1407) chore(release): release Buzz Desktop version 0.3.39 (#1410) fix: close cross-process keychain race and namespace dev-build nest (#1409) feat(relay): allow agent owners to edit/manage agent-owned content (#1403) fix(media): support IRSA/credential-chain S3 auth and configurable signing region (#1406) fix(desktop): fold baked build env into in-process model discovery (#1376) docs: link VISION_ACTIVITY from the VISION index (#1405)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
Scrolling back through channels with mixed message types (images, code, link previews, video thumbs) jumped hard. Every timeline row used a flat
content-visibility: auto 60pxplaceholder, so never-painted rows snapped from 60px to true height as they realized on scroll-up, shoving the column — the #buzz-bugs scrollback-jump Wes reported.Changes
Two targeted fixes:
rowHeightEstimate.ts): reserve a crediblecontain-intrinsic-sizeper row derived from its content (text lines, fenced code, imeta media dims, bare media URLs, link-preview cards). Drift through a mixed-media scrollback drops ~20x (1538px flat-60 baseline → ~66–96px).markdown.tsx/markdown/utils.ts): images without a NIP-92dimreserve a stable box and cache decoded natural size by URL, so they decode into reserved space instead of popping the row.TimelineMessageList.tsxwires the per-row estimate into the row reserve style.Tests
rowHeightEstimateunit coverage (11 cases: text, code, imeta with/without dim, bare media URLs, no double-counting, divider sizing).timeline-no-shiftmixed-media e2e gate (bounded first-pass prepend drift, no-shiftmaxDrift 0).Not in scope / known follow-up
useAnchoredScroll.ts) regressed cold-load "start at bottom" and was reverted — this PR leaves the anchored-scroll path untouched frommain.mainand not addressed here; it needs an explicit bottom-intent/loader protocol. The twoscroll-historye2e failures observed are pre-existing onmain(verified on a pristinemainworktree), not regressions from this branch.