fix: make "jump to solution" reach the solution reply - #921
Open
rawsun007 wants to merge 1 commit into
Open
Conversation
Replies render inside a virtualized, cursor paginated list, so #solution-<id> points at an element that is not in the DOM and the browser has nothing to scroll to. The click handler only flipped showAllMessages, which nothing reads. SnapshotInfiniteList now accepts getItemId/registerScroller, pages forward until the target item is loaded and calls scrollToIndex so it mounts. MessageResultPageProvider routes JumpToSolution, ReplyBar and the ?focus= param through that, and holds a #solution- deep link until the list registers itself.
|
@rawsun007 is attempting to deploy a commit to the Answer Overflow Team on Vercel. A member of the Team first needs to authorize it. |
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.
Fixes #892
The bug
Clicking "Jump to solution" does nothing, and opening a page with a
#solution-<id>hash does nothing either.Replies are rendered by
SnapshotInfiniteList, which is areact-virtuosowindow list on top of cursor pagination. Two things follow from that:So
#solution-<id>points at an element that is not in the DOM, and the browser's native anchor scroll has nothing to scroll to.The same applies to the two existing code paths that tried to handle this:
JumpToSolutiononly calledsetShowAllMessages(true), and nothing in the app ever readshowAllMessages- it was dead state - so the click relied entirely on the native anchor.?focus=effect inmessage-page.tsxdid a singlegetElementByIdon mount, before the replies had loaded, and silently gave up when it returned null.ReplyBar'sscrollToMessagehad the same one-shotgetElementByIdbehaviour and fell back to a full page navigation.The fix
Teach the list to reach an item that is not loaded or not mounted yet, and route every "scroll to this message" caller through it.
SnapshotInfiniteListtakes an optionalgetItemIdandregisterScroller. The scroller looks the item up in what is loaded; if it is not there it keeps requesting the next page and retries as pages arrive, then callsVirtuoso.scrollToIndexso the item actually mounts.onScrolledToItemis retried for a few frames because the row mounts after the scroll.MessageResultPageProviderownsscrollToMessage: it tries the DOM first (the solution card at the top of the page is not virtualized), then hands off to the list. If the click happens before the list has mounted, the target is held and flushed when the list registers, which is what makes a#solution-<id>deep link work on load.JumpToSolutioncallsscrollToMessageand only prevents the default anchor when the scroll was handled, so nothing regresses where there is no list.?focus=handling moved into the provider, so it goes through the same path instead of its own one-shot lookup.showAllMessages/setShowAllMessagesfrom the context - nothing read them.The paging-vs-give-up decision is
resolveScrollTargetinpackages/ui/src/utils/scroll-target.ts, kept pure so it can be tested directly.messageIdFromHashparses the deep link and ignores anything that is not a snowflake.Tests
packages/ui/src/utils/scroll-target.test.tscovers the hash parsing and the resolver, including the case this bug was: target not loaded and pagination not finished has to load more rather than resolve to nothing.packages/ui/src/components/jump-to-solution.test.tsxrenders the provider with a stand-in list and asserts that a click, and a#solution-<id>on load, actually reach the list.On this branch:
With the component tests kept and the fix reverted, the behaviour they describe is gone:
bun run lintandtsgo --noEmiton@packages/uiand@apps/main-siteare clean.Known limit
The replies list also has crawlable cursor pagination. If the solution is on an earlier cursor page than the one being viewed, the list cannot page backwards to it, so
scrollToMessagereturns false and the plain anchor navigation happens as before. The common case (/m/<id>with no cursor) walks forward from the start and reaches it.