fix: stop windowed diff/list scroll flashes and jumps - #34
Merged
Merged
Conversation
- windowing: key measured heights by row identity so inserting a card, expanding context or loading more commits no longer discards them; scrollTo renders the target window before paint and re-aligns until measured heights settle - TextDiff: scroll-to effects run as layout effects, fire once the container exists (cross-file focus), and no longer re-center when the same file reloads - Explain references scroll through the windowed diff (revealLine in the diff store) instead of querying rendered rows, fixing far-away lines and the 250ms file-switch race - Changes list no longer resets row heights on every status refresh
A first align that doesn't move no longer drops the target: the settle pass re-checks against measured heights and freshly rendered spacers, covering a 'nearest' row whose estimate looked in view and a 'center' clamped by a stale scroll height.
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.
Problem
Opening an AI review finding's inline card made the diff flash and jump.
useWindowedRowsstored measured row heights by index and discarded all of them whenever the row count changed (inserting the card row).TextDiffthen scrolled in a post-paintuseEffectusing guessed offsets, painted a blank frame until the scroll event re-rendered, and never re-centred once real heights were measured.The same mechanism affected blame cards, hunk context expansion, the History search highlight, Explain references, History pagination on phones, and the conflict view's low-confidence jump.
Changes
lib/windowing.ts: measured heights are keyed by row identity (keyOf), so inserting or removing rows keeps every other row's height.scrollTorenders the target window before paint and re-aligns after each measurement pass until the position settles (capped at 8 passes). The scroll/ResizeObserver effect no longer re-subscribes on every count change.TextDiff: scroll-to effects areuseLayoutEffects. They fire once the scroll container exists, which fixes cross-file finding focus never scrolling, and no longer re-centre when the same file reloads.diff.revealLineand the windowedscrollToinstead of looking for the row in the page. Lines outside the rendered window were silently ignored before, and the 250 ms file-switch timeout is gone. The flash highlight is rendered byTextDiff.resetKeyis now the repo path instead of thestatusobject, so measured heights are not thrown away on every status refresh.Verification
main: 2000-line file, wrap on, injected pre-commit findings, per-frame measurement after each click.main: a blank first frame on far jumps; the target lands 90–150 px below centre.maindoes not scroll; this branch centres and flashes the line.0b534ea.Not exercised directly: History "load more" on a phone viewport and the conflict view's low-confidence jump. Both go through the shared windowing change.