v3: various improvements and fixes to real-time updates
All checks were successful
Build and Publish Docker Image / build-and-push (push) Successful in 40s
All checks were successful
Build and Publish Docker Image / build-and-push (push) Successful in 40s
This commit is contained in:
@@ -82,6 +82,7 @@ export function Dump() {
|
||||
removeVote,
|
||||
lastDumpEvent,
|
||||
lastCommentEvent,
|
||||
connectionEpoch,
|
||||
} = useWS();
|
||||
|
||||
useEffect(() => {
|
||||
@@ -157,7 +158,9 @@ export function Dump() {
|
||||
})
|
||||
.catch(() => {});
|
||||
return () => controller.abort();
|
||||
}, [selectedDump, token]);
|
||||
// connectionEpoch: re-fetch on reconnect to backfill comments missed while
|
||||
// the socket was down.
|
||||
}, [selectedDump, token, connectionEpoch]);
|
||||
|
||||
// Fetch related dumps (backlinks) when dump loads
|
||||
useEffect(() => {
|
||||
|
||||
@@ -70,6 +70,7 @@ export function Index({ categorySlug }: { categorySlug?: string }) {
|
||||
deletedDumpIds,
|
||||
castVote,
|
||||
removeVote,
|
||||
connectionEpoch,
|
||||
} = useWS();
|
||||
|
||||
// Resolve the scope to a real category (for its id, name, and 404 handling).
|
||||
@@ -177,6 +178,36 @@ export function Index({ categorySlug }: { categorySlug?: string }) {
|
||||
);
|
||||
useDumpListSync(setDumpsItems);
|
||||
|
||||
// ── Reconnect backfill ──
|
||||
|
||||
// New dumps that arrived while the socket was down weren't delivered. On
|
||||
// reconnect, re-fetch page 1 and merge anything not already present on top,
|
||||
// preserving loaded pages and scroll position.
|
||||
const backfillEpochRef = useRef(connectionEpoch);
|
||||
useEffect(() => {
|
||||
if (connectionEpoch === backfillEpochRef.current) return;
|
||||
backfillEpochRef.current = connectionEpoch;
|
||||
const controller = new AbortController();
|
||||
fetch(feedUrl(1), {
|
||||
signal: controller.signal,
|
||||
headers: token ? { Authorization: `Bearer ${token}` } : {},
|
||||
})
|
||||
.then((r) => r.json())
|
||||
.then((body) => {
|
||||
const { items } = body.data as PaginatedData<RawDump>;
|
||||
const fresh = items.map(deserializeDump);
|
||||
setDumpsState((s) => {
|
||||
if (s.status !== "loaded") return s;
|
||||
const known = new Set(s.dumps.map((d) => d.id));
|
||||
const newOnes = fresh.filter((d) => !known.has(d.id));
|
||||
if (newOnes.length === 0) return s;
|
||||
return { ...s, dumps: [...newOnes, ...s.dumps] };
|
||||
});
|
||||
})
|
||||
.catch(() => {});
|
||||
return () => controller.abort();
|
||||
}, [connectionEpoch, feedUrl, token]);
|
||||
|
||||
// ── Load more ──
|
||||
|
||||
const loadMore = useCallback(() => {
|
||||
|
||||
Reference in New Issue
Block a user