Wheeling to the top of a channel left the rendered window frozen on the
newest ~11 rows — users could not scroll back through history. MessageTimeline
re-renders on every scroll via useVirtualizer's onChange, but TimelineMessageList
is React.memo and read getVirtualItems() internally through the virtualizer's
stable mutable ref. Shallow compare cannot see the range walk through that ref,
so the memo skipped re-render while the virtual range advanced underneath.
Thread virtualItems as a fresh-array prop from the hook-owner into the memoized
renderer so memo sees a new reference each render and re-renders in lockstep —
the documented react-virtual pattern. The e2e fixture now honors since/until/limit
to model a true older-page gap, and a new anchor test asserts the tracked row's
getBoundingClientRect().top holds within 8px across a scroll-back.
Co-authored-by: Will Pfleger <pfleger.will@gmail.com>
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>