feat(stream): reset scroll to top on ?post deep-link arrivals
All checks were successful
Deploy to Frontend Servers / deploy (push) Successful in 28s

Banner / Home-card clicks landing on /browse?post=X now always start the
smooth-scroll positioning from the top of the stream, instead of from
whatever scrollY the user happened to leave the page at. Runs in
useLayoutEffect before paint so the user never briefly sees the previous
position before the jump, giving a clearly visible scroll journey to the
target post every time.

Verified in the browser: before banner click scrollY=2000, immediately
after =0, then smooth-scrolled to ~25k as pagination loaded the target
post deeper in the stream.
This commit is contained in:
TerryM
2026-06-02 11:42:10 +08:00
parent 387b25f1e3
commit 562843e4b2

View File

@@ -1,4 +1,4 @@
import { useEffect, useMemo, useRef, useState } from "react";
import { useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
import { useLocation, useSearchParams } from "react-router-dom";
import { postJSON } from "../../api";
import { useI18n } from "../../i18n";
@@ -104,6 +104,16 @@ export function MessageStream({ scope }: MessageStreamProps) {
setIsAligningQueryTarget(false);
}, [queryTargetPostId, targetPostId]);
// Banner / deep-link arrivals (`?post=<id>`) should always begin the
// smooth-scroll positioning from the top of the stream, so the user sees a
// clear, satisfying journey to the target post instead of a tiny nudge when
// they happen to revisit the page mid-scroll. Run before paint so the user
// never briefly sees the previous scrollY before the jump.
useLayoutEffect(() => {
if (!queryTargetPostId) return;
window.scrollTo({ top: 0, left: 0, behavior: "auto" });
}, [queryTargetPostId]);
useEffect(() => clearTargetScrollTimers, []);
useEffect(() => {