Channels: persistent reply row to stop feed scroll jitter#3324
Draft
adboio wants to merge 1 commit into
Draft
Conversation
The channel feed only mounted a task's reply teaser once the row scrolled
into the IntersectionObserver band, and the teaser rendered nothing until its
thread fetch resolved. On the first scroll up from the bottom of a feed (rows
that have never been fetched), the fetch routinely landed after the row was
already visible, so "N replies" popped in and shoved the layout down.
Replace the `{inView && <RepliesRow/>}` gate with a persistent `ReplyFooter`
that is always rendered at a constant height: the teaser once the thread has
messages, and a quiet always-visible "Reply" affordance otherwise. Both states
use the same avatar-sized row, so the teaser swaps in after the fetch without
shifting the feed. As a bonus this surfaces a discoverable way into a thread
instead of leaving it in the hover toolbar.
The thread fetch/poll is still gated to near-viewport rows via a new `enabled`
option on `useTaskThread` (passed `inView`), so a long feed does not poll every
row; off-screen rows render the static affordance and idle.
Generated-By: PostHog Code
Task-Id: 5ac91104-20d5-4df7-a82a-3362086bde3a
|
React Doctor found no issues in the changed files. 🎉 Reviewed by React Doctor for commit |
|
Merging to
After your PR is submitted to the merge queue, this comment will be automatically updated with its status. If the PR fails, failure details will also be posted here |
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
In channels, scrolling up through the feed caused visible layout jitter: a message with a human thread would come into view, and a beat later its "N replies" teaser would pop in and push the feed down. The teaser was only mounted once a row scrolled near the viewport, and rendered nothing until its thread fetch resolved — so on the first scroll up from the bottom (rows that have never been fetched) the fetch routinely landed after the row was already visible.
Why: Reported from the Channels (project-bluebird) experience — the late-attaching reply teaser makes scrolling feel unstable, and the existing way to start a thread was hidden in the hover toolbar.
Changes
RepliesRowwith a persistentReplyFooter, rendered at a constant height for every message: the reply teaser once the thread has messages, and a quiet always-visible Reply affordance otherwise. Both states share the same avatar-sized row, so the teaser swaps in after the fetch with no layout shift.enabledflag touseTaskThreadso only near-viewport rows fetch/poll; off-screen rows show the static affordance and idle, keeping a long feed from polling every row.Height parity between the two states relies on both using the same
AvatarGroup size="xs"row — worth an eyeball in review, but the swap is now a content change, not a0 → teaserheight jump.How did you test this?
pnpm --filter @posthog/ui typecheck— passes.checkon the two changed files — clean.Automatic notifications
Created with PostHog Code