fix: user post feed view
This commit is contained in:
@@ -41,6 +41,10 @@ export function usePostScrollFeed(fetchPage: FetchPage) {
|
|||||||
const startedRef = useRef(false);
|
const startedRef = useRef(false);
|
||||||
const cursorRef = useRef<FeedCursor | null>(null);
|
const cursorRef = useRef<FeedCursor | null>(null);
|
||||||
const anchorIdRef = useRef<string | null>(null);
|
const anchorIdRef = useRef<string | null>(null);
|
||||||
|
// Every post id we've already appended — used to dedupe AND to detect a
|
||||||
|
// stalled cursor (a page that adds nothing new), which we treat as the end
|
||||||
|
// so a backend ordering hiccup can never become an infinite fetch loop.
|
||||||
|
const idsRef = useRef<Set<string>>(new Set());
|
||||||
|
|
||||||
// Append the next older page, keyed off the last loaded post.
|
// Append the next older page, keyed off the last loaded post.
|
||||||
const loadOlder = useCallback(async () => {
|
const loadOlder = useCallback(async () => {
|
||||||
@@ -48,13 +52,15 @@ export function usePostScrollFeed(fetchPage: FetchPage) {
|
|||||||
fetchingRef.current = true;
|
fetchingRef.current = true;
|
||||||
try {
|
try {
|
||||||
const rows = (await fetchPage(cursorRef.current, PAGE)) ?? [];
|
const rows = (await fetchPage(cursorRef.current, PAGE)) ?? [];
|
||||||
setFeed((prev) => {
|
const fresh = rows.filter((p) => !idsRef.current.has(p.id));
|
||||||
const seen = new Set(prev.map((p) => p.id));
|
if (fresh.length > 0) {
|
||||||
const merged = [...prev, ...rows.filter((p) => !seen.has(p.id))];
|
fresh.forEach((p) => idsRef.current.add(p.id));
|
||||||
if (merged.length > 0) cursorRef.current = cursorOf(merged[merged.length - 1]);
|
// rows come back newest→oldest; the oldest fresh row is the next cursor.
|
||||||
return merged;
|
cursorRef.current = cursorOf(fresh[fresh.length - 1]);
|
||||||
});
|
setFeed((prev) => [...prev, ...fresh]);
|
||||||
if (rows.length < PAGE) setHasMore(false);
|
}
|
||||||
|
// Stop on a short page OR a page that produced nothing new (stalled).
|
||||||
|
if (rows.length < PAGE || fresh.length === 0) setHasMore(false);
|
||||||
} catch {
|
} catch {
|
||||||
setHasMore(false);
|
setHasMore(false);
|
||||||
setError((e) => e ?? "Could not load posts.");
|
setError((e) => e ?? "Could not load posts.");
|
||||||
@@ -80,6 +86,7 @@ export function usePostScrollFeed(fetchPage: FetchPage) {
|
|||||||
if (anchor) {
|
if (anchor) {
|
||||||
anchorIdRef.current = anchor.id;
|
anchorIdRef.current = anchor.id;
|
||||||
cursorRef.current = cursorOf(anchor);
|
cursorRef.current = cursorOf(anchor);
|
||||||
|
idsRef.current.add(anchor.id);
|
||||||
setFeed([anchor]);
|
setFeed([anchor]);
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
await loadOlder(); // posts older than the anchor
|
await loadOlder(); // posts older than the anchor
|
||||||
|
|||||||
Reference in New Issue
Block a user