Merge chore/code-hygiene: fix Plex infinite-scroll dead after drill-in→Back
Callback-ref the grid's IntersectionObserver sentinel so it re-attaches on the grid's unmount/remount cycle (drill into info/show/season → Back), instead of observing a detached old node and freezing the feed at the loaded pages.
This commit is contained in:
commit
1df6ddd154
1 changed files with 10 additions and 7 deletions
|
|
@ -156,21 +156,24 @@ export default function PlexBrowse({
|
||||||
// Episode matches (grouped "Episodes" section) — search-only; same set on every page, take page 0.
|
// Episode matches (grouped "Episodes" section) — search-only; same set on every page, take page 0.
|
||||||
const episodes = browseQ.data?.pages[0]?.episodes ?? [];
|
const episodes = browseQ.data?.pages[0]?.episodes ?? [];
|
||||||
|
|
||||||
// Infinite scroll: auto-load the next page when the sentinel scrolls into view.
|
// Infinite scroll: auto-load the next page when the sentinel scrolls into view. The sentinel lives
|
||||||
const sentinel = useRef<HTMLDivElement>(null);
|
// in the grid branch, which UNMOUNTS when we drill into an info/show/season page and remounts on
|
||||||
|
// Back — as a NEW element. A callback ref (state, not useRef) re-runs this effect on every
|
||||||
|
// mount/unmount, so the observer always watches the live node; a plain ref would keep observing the
|
||||||
|
// detached old node after Back and never fire fetchNextPage again (feed stuck at the loaded pages).
|
||||||
|
const [sentinelEl, setSentinelEl] = useState<HTMLDivElement | null>(null);
|
||||||
const { hasNextPage, isFetchingNextPage, fetchNextPage } = browseQ;
|
const { hasNextPage, isFetchingNextPage, fetchNextPage } = browseQ;
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const el = sentinel.current;
|
if (!sentinelEl) return;
|
||||||
if (!el) return;
|
|
||||||
const io = new IntersectionObserver(
|
const io = new IntersectionObserver(
|
||||||
(entries) => {
|
(entries) => {
|
||||||
if (entries[0].isIntersecting && hasNextPage && !isFetchingNextPage) fetchNextPage();
|
if (entries[0].isIntersecting && hasNextPage && !isFetchingNextPage) fetchNextPage();
|
||||||
},
|
},
|
||||||
{ rootMargin: "600px" },
|
{ rootMargin: "600px" },
|
||||||
);
|
);
|
||||||
io.observe(el);
|
io.observe(sentinelEl);
|
||||||
return () => io.disconnect();
|
return () => io.disconnect();
|
||||||
}, [hasNextPage, isFetchingNextPage, fetchNextPage]);
|
}, [sentinelEl, hasNextPage, isFetchingNextPage, fetchNextPage]);
|
||||||
|
|
||||||
function onCard(card: PlexCard) {
|
function onCard(card: PlexCard) {
|
||||||
scrollRef.current = scroller()?.scrollTop ?? 0; // remember grid position for the trip back
|
scrollRef.current = scroller()?.scrollTop ?? 0; // remember grid position for the trip back
|
||||||
|
|
@ -345,7 +348,7 @@ export default function PlexBrowse({
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div ref={sentinel} className="h-8" />
|
<div ref={setSentinelEl} className="h-8" />
|
||||||
{isFetchingNextPage && <p className="text-center text-xs text-muted pb-4">{t("plex.loading")}</p>}
|
{isFetchingNextPage && <p className="text-center text-xs text-muted pb-4">{t("plex.loading")}</p>}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue