Repository navigation
Conversation
…ecolua#3838) The console log wrote `scrollTop = scrollHeight` on every append: useEffect(() => { if (!logRef.current) return; logRef.current.scrollTop = logRef.current.scrollHeight; }, [logs]); So scrolling up to read an older line lasted until the next entry arrived. Something is always appending -- a combo fanning out to several models, a background token refresh -- which is what makes this unreadable rather than merely awkward: the reporter could not see which member of a fusion had failed. Following the tail is now a property of where the reader already is. It is recorded on scroll, not read inside the effect, because by the time the effect runs the new lines are laid out and the element no longer reports where the reader was before they arrived. The comparison carries a few pixels of slack rather than testing equality. `scrollHeight` and `clientHeight` are integers while `scrollTop` is fractional under a non-integer device pixel ratio, so an element sitting at its bottom routinely reports a residue -- an exact test would drop the reader out of follow mode without them having scrolled at all. The decision lives in a plain function because the test environment is `node` with no DOM, so a component test could not have run. Verified: 7 tests, and each claim checked by reverting it -- comparing exactly fails the sub-pixel case, always-following fails the older-lines case. `next build` compiles. The install log in EndpointPageClient.js has the same unconditional scroll. It is left alone: it runs for the length of one install, with nothing older to read.
user177013
added a commit
to user177013/9router
that referenced
this pull request
Nov 15, 2026
Cherry-pick the scroll-follow behavior from PR decolua#3872. Co-authored-by: Copilot <[email protected]>
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.
Closes #3838.
The console log scrolled to the bottom on every append:
So scrolling up to read an older line lasted until the next entry arrived. And something is always appending — a combo fanning out to several models, a background token refresh — which is what makes it unreadable rather than merely awkward. The reporter could not see which member of a fusion had failed.
The change
Following the tail becomes a property of where the reader already is: at the bottom means keep me there, anywhere else means leave me alone.
Two details that are not obvious:
scrollHeightandclientHeightare integers whilescrollTopis fractional under a non-integer device pixel ratio, so an element sitting at its bottom routinely reports a residue of a pixel or two. An exact test drops the reader out of follow mode without them having scrolled.The decision lives in a plain function (
src/shared/utils/scrollFollow.js) becausetests/vitest.config.jsruns withenvironment: "node"and there is no React testing setup — a component test could not have run at all, and I would rather have a real test of the rule than none.Verification
tests/unit/scroll-follow.test.js— 7 passed. Each claim checked by reverting it:npx next build— ✓ compiled successfully.Not changed
EndpointPageClient.jshas the same unconditional scroll for the Tailscale install log. Left alone deliberately: it runs for the length of one install and has nothing older to read. The helper is there if you want it applied.