From fcdacbcdf65ffa4166360451b1bc1fa89d1e372d Mon Sep 17 00:00:00 2001 From: Arjun Patel Date: Tue, 9 Jun 2026 09:44:10 -0700 Subject: [PATCH] paginate for open and closed streams --- js/desktop/src/hooks/use-stream-particles.ts | 25 ++++++-------------- 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/js/desktop/src/hooks/use-stream-particles.ts b/js/desktop/src/hooks/use-stream-particles.ts index 41bcae1..b7db180 100644 --- a/js/desktop/src/hooks/use-stream-particles.ts +++ b/js/desktop/src/hooks/use-stream-particles.ts @@ -10,8 +10,8 @@ export type StreamParticle = Particle & { properties: StreamProperties; }; -const CLOSED_INITIAL_PAGE_SIZE = 50; -const CLOSED_PAGE_INCREMENT = 50; +const INITIAL_PAGE_SIZE = 3; +const PAGE_INCREMENT = 3; // Stable where-constraint references so the Firestore subscription only // re-attaches when the tab actually changes, not on every render. @@ -33,6 +33,7 @@ interface UseStreamParticlesOptions { * by active work — full realtime coverage is needed for autoplay/huddles). * Closed streams are paginated via `loadMore`. */ + // TODO: can't we paginate open streams, and if the top set changes then our auto-play would still trigger? status: 'open' | 'closed'; } @@ -54,21 +55,10 @@ export function useStreamParticles( const user = useAuthStore((s) => s.user); const visibilityScopes = useVisibilityScopes(user?.id, networkId); - const [closedLimit, setClosedLimit] = useState(CLOSED_INITIAL_PAGE_SIZE); - const [prevStatus, setPrevStatus] = useState(status); - - // Switching back to the closed tab starts a fresh window, avoiding an - // ever-growing subscription across a long session. - if (status !== prevStatus) { - setPrevStatus(status); - if (status === 'closed') { - setClosedLimit(CLOSED_INITIAL_PAGE_SIZE); - } - } + const [limit, setLimit] = useState(INITIAL_PAGE_SIZE); const whereFilter: QueryFieldFilterConstraint = status === 'open' ? OPEN_STATUS_FILTER : CLOSED_STATUS_FILTER; - const limit = status === 'closed' ? closedLimit : undefined; const { children, isLoading } = useLiveParticleChildren(path, { orderByField: 'last_child_created_at', @@ -85,12 +75,11 @@ export function useStreamParticles( // Heuristic: if we got back as many items as we asked for, assume there // might be more. Clicking load-more when there are no more is a no-op. - const canLoadMore = status === 'closed' && streams.length >= closedLimit; + const canLoadMore = streams.length >= limit; const loadMore = useCallback(() => { - if (status !== 'closed') return; - setClosedLimit((prev) => prev + CLOSED_PAGE_INCREMENT); - }, [status]); + setLimit((prev) => prev + PAGE_INCREMENT); + }, []); return { streams, isLoading, networkId, canLoadMore, loadMore }; }