import React from 'react'; import { fetchGallery } from '../services/photosApi'; export type GalleryDelta = { photos: Record[]; latestPhotoAt: string | null; nextCursor: string | null; }; const emptyDelta: GalleryDelta = { photos: [], latestPhotoAt: null, nextCursor: null, }; export function usePollGalleryDelta( eventToken: string | null, options: { intervalMs?: number; locale?: string } = {} ) { const intervalMs = options.intervalMs ?? 30000; const [data, setData] = React.useState(emptyDelta); const [loading, setLoading] = React.useState(Boolean(eventToken)); const [error, setError] = React.useState(null); const latestRef = React.useRef(null); React.useEffect(() => { if (!eventToken) { setData(emptyDelta); setLoading(false); setError(null); latestRef.current = null; return; } let active = true; let timer: number | null = null; const poll = async () => { if (document.visibilityState === 'hidden') { timer = window.setTimeout(poll, intervalMs); return; } try { setLoading(true); const response = await fetchGallery(eventToken, { since: latestRef.current ?? undefined, locale: options.locale, }); if (!active) return; const photos = Array.isArray(response.data) ? response.data : []; const latestPhotoAt = response.latest_photo_at ?? latestRef.current ?? null; latestRef.current = latestPhotoAt; setData({ photos, latestPhotoAt, nextCursor: response.next_cursor ?? null, }); setError(null); } catch (err) { if (!active) return; setError(err instanceof Error ? err.message : 'Failed to load gallery updates'); } finally { if (active) { setLoading(false); timer = window.setTimeout(poll, intervalMs); } } }; poll(); return () => { active = false; if (timer) { window.clearTimeout(timer); } }; }, [eventToken, intervalMs, options.locale]); return { data, loading, error } as const; }