Skip to content

fix(ui): fill the review stream on first paint (0.20.x) - #926

Open
benvinegar wants to merge 3 commits into
0.20.xfrom
backport/922-0.20.x
Open

fix(ui): fill the review stream on first paint (0.20.x)#926
benvinegar wants to merge 3 commits into
0.20.xfrom
backport/922-0.20.x

Conversation

@benvinegar

Copy link
Copy Markdown
Member

Summary

Backports #922 onto the 0.20.x maintenance branch.

  • estimate the viewport while OpenTUI layout is still unmeasured so nowrap file windowing fills the first frame
  • render edge-jump destinations before moving the native viewport
  • stabilize viewport resize subscriptions and equivalent line-cursor identity
  • add unit, interaction, and PTY regression coverage

The runtime changes applied cleanly apart from App.tsx, where the backport retains the 0.20.x transient-notice implementation. PTY conflicts were resolved against the maintenance branch test layout without bringing unrelated main-only coverage.

Verification

  • bun run typecheck
  • bun run lint
  • bun run format:check
  • bun run deps:check
  • focused viewport, windowing, interaction, and component tests: 199 passed
  • first-frame PTY regression: passed
  • bun run test: both shards passed (1,547 + 1,510 tests)
  • bun run test:integration: 130 passed
  • bun run test:tty-smoke: 9 passed
  • real-TTY source smoke against origin/0.20.x, including first paint and G
  • bun run changeset:status -- --since=origin/0.20.x: patch bump for hunkdiff

File windowing treated an unmeasured scrollbox height as 0, so only the leading file plus one overscan neighbor mounted until the user scrolled. Use the estimated viewport height for that first paint and re-read once after layout.\n\n(cherry picked from commit d570d2f)
@vercel

vercel Bot commented Aug 30, 2026

Copy link
Copy Markdown

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

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
hunk-web Ignored Ignored Preview Aug 30, 2026 9:31pm

Request Review

@greptile-apps

greptile-apps Bot commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This backport estimates the initial review viewport, pre-renders edge-jump destinations, stabilizes viewport and cursor identities, and adds regression coverage.

  • Adds first-paint viewport estimation for nowrap file windowing.
  • Routes top/bottom commands through render-first edge requests.
  • Revises viewport subscriptions and equivalent line-cursor reuse.
  • Adds unit, interaction, component, and PTY coverage.

Confidence Score: 3/5

The PR should not merge until viewport measurement uses the actual OpenTUI event contract and edge jumps supersede pending selection-reveal retries.

The initial geometry callback can be missed because it subscribes to an undocumented event name, and a recently scheduled hunk-reveal retry can override an explicit top or bottom jump.

Files Needing Attention: src/ui/components/panes/DiffPane.tsx

Important Files Changed

Filename Overview
src/ui/App.tsx Converts content-edge scrolling into monotonic render-first requests passed to DiffPane.
src/ui/components/panes/DiffPane.tsx Adds initial viewport estimation, edge-jump rendering, viewport subscription changes, and cursor identity reuse; the new event subscription and pending-reveal interaction need correction.
src/ui/lib/viewportTiming.ts Adds bounded initial-height estimation and measured-height fallback helpers.
src/ui/lib/lineCursors.ts Reuses cursor arrays only when every navigation field remains equivalent.
test/pty/layout.test.ts Adds real-terminal regression coverage for filling a tall first nowrap frame.

Sequence Diagram

sequenceDiagram
  participant U as User
  participant A as App
  participant D as DiffPane
  participant O as OpenTUI viewport
  U->>A: G or gg
  A->>D: scrollEdgeRequest
  D->>D: Render destination rows
  D->>O: scrollTo(edge)
  O-->>D: Viewport geometry event
  D->>D: Refresh windowed rows
Loading
Prompt To Fix All With AI
### Issue 1
src/ui/components/panes/DiffPane.tsx:831
**Viewport resize event is misnamed**

When the scrollbox publishes its measured geometry, this listener waits for `resize` instead of OpenTUI's documented `resized` event, leaving `scrollViewport.height` at zero or stale and causing windowing to leave blank review rows until another scroll triggers a read.

```suggestion
      scrollBox.viewport.on("resized", handleViewportResize);
```

### Issue 2
src/ui/components/panes/DiffPane.tsx:972-995
**Pending reveal overrides edge jumps**

When G or gg is pressed during the 120 ms selected-hunk settling period, this effect moves to the requested edge without cancelling the pending reveal; the later reveal observes the pinned-header change and scrolls back to the selected hunk, so the command lands at the wrong position.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Reviews (1): Last reviewed commit: "fix(ui): stabilize viewport startup timi..." | Re-trigger Greptile

Comment thread src/ui/components/panes/DiffPane.tsx
Comment thread src/ui/components/panes/DiffPane.tsx
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