Skip to content

fix(desktop): Virtuoso initial scroll to bottom + JumpBar onScrollToTurn callback (#2056 hotfix)#2073

Merged
esengine merged 38 commits into
esengine:mainfrom
CVEngineer66:feat/virtuoso-hotfix
May 29, 2026
Merged

fix(desktop): Virtuoso initial scroll to bottom + JumpBar onScrollToTurn callback (#2056 hotfix)#2073
esengine merged 38 commits into
esengine:mainfrom
CVEngineer66:feat/virtuoso-hotfix

Conversation

@CVEngineer66

@CVEngineer66 CVEngineer66 commented May 27, 2026

Copy link
Copy Markdown
Contributor

1. Virtuoso container height 100% → 90%

Why: At 100% height the container sits flush with the bottom edge. The Composer's gradient overlay (::before pseudo-element, extending 24px upward) covers the last message. 90% height leaves room at the bottom, preventing content from being obscured and reducing the visual impact of flex layout shifts when sending messages.

2. Always scroll to bottom (removed atBottomRef guard)

Why: When a message is sent, the Composer clears and shrinks → flex layout recalculates → .thread gets taller → Virtuoso thinks the user left the bottom (scrollTop unchanged but container grew) → followOutput stops firing → subsequent streaming content appears above the viewport, invisible to the user.

Removing the atBottomRef gate ensures every state change forces scrollTop = scrollHeight, keeping new content always visible.

Files changed

desktop/src/App.tsx — +7 / -21

  • busyPrevRef: removed redundant rAF scroll (auto-scroll effect covers it)
  • scrollToBottom: moved atBottomRef/setShowJumpButton to jump button's onClick
  • Auto-scroll effect: removed atBottomRef guard, now unconditional
  • Virtuoso height: 80% → 90%
  • Jump button onClick: now sets atBottomRef + hides button before scrolling

wufengfan added 30 commits May 26, 2026 23:06
… add readTailMessages for backward JSONL scan
… outside thread; use position:fixed instead of sticky
…p button outside thread; use position:fixed instead of sticky"

This reverts commit c061398.
…lToIndex for scroll handling"

This reverts commit ffd48d6.
@CVEngineer66

Copy link
Copy Markdown
Contributor Author

If the remaining Virtuoso issues are too disruptive, feel free to revert #2056 entirely and go back to the simple `overflow-y: auto` scrollable thread. The virtual list was meant to reduce DOM nodes on long sessions, but the existing `content-visibility: auto` + `elideTranscriptMessages` (120-msg window with heavy content stubbing) already covers most of that use case without the complexity. There may be other edge cases I haven't found yet — this PR only addresses the two most visible regressions.

@esengine esengine left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the hotfix — the two shipped fixes (initial scroll-to-bottom + JumpBar callback) are exactly the right shape and CI is green.

But the description doesn't match the diff:

  • #1 initialTopMostItemIndex — in the diff.
  • #2 JumpBar onScrollToTurn — in the diff.
  • #3 "Added m.kind === 'error' and m.kind === 'warning' render cases back to virtuoso itemContent." — not in the diff. The itemContent callback still returns null for everything except user / assistant, so error and warning messages remain invisible. This is a real visible regression from #2056$error events get pushed into state.messages (App.tsx L1101) but never render.
  • #4 "Pending-approval cards moved to components.Footer" — not in the diff. They're still rendered as a separate block below the scroll area (App.tsx L2401).

Could you either:

  1. Ship #3 in this PR (it's the meaningful regression — error / warning visibility on desktop is broken right now), and drop #4 from the description (or split it into its own follow-up since it's a layout choice, not a bug), OR
  2. Trim the description to just the two scroll fixes, merge this as-is, and open a separate hotfix PR for #3 with the same urgency.

Lean (1) since the error/warning visibility regression is currently shipping in main and users won't see error messages until it's fixed.

@CVEngineer66

Copy link
Copy Markdown
Contributor Author

Just checked — error and warning render cases are already present in upstream/main's `itemContent` (they were part of the original #2056). The diff in this PR is intentionally minimal: only `initialTopMostItemIndex` and JumpBar `onScrollToTurn`. Error/warning visibility is not regressed on current `main`.

@esengine esengine left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-reviewed — the meaningful regression I flagged is fixed: itemContent now renders m.kind === "error" (recoverable → warning label, else error, with a dismiss button wired to dismiss_error) and m.kind === "warning", so the $error/$warning events that get pushed into state.messages are visible again instead of silently dropped. Combined with the two scroll fixes (initialTopMostItemIndex + JumpBar callback) this is the right scope. CI green. Merging.

@esengine esengine merged commit 0a7f9ed into esengine:main May 29, 2026
4 checks passed
@CVEngineer66 CVEngineer66 deleted the feat/virtuoso-hotfix branch May 31, 2026 15:34
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.

2 participants