63 lines
1.9 KiB
TypeScript
63 lines
1.9 KiB
TypeScript
import { useEffect, useMemo, useState } from "react";
|
|
import { useLiveParticleChildren } from "@/hooks/use-particle";
|
|
import { useAuthStore } from "@/stores/auth-store";
|
|
import { parseParticlePath, type ParticlePath } from "@/lib/particle-path";
|
|
import type { Particle, StreamProperties } from "@/api/types";
|
|
import { where, Timestamp } from "firebase/firestore";
|
|
import { RECENCY_WINDOW_HOURS } from "@/lib/constants";
|
|
|
|
type StreamParticle = Particle & { type: "stream"; properties: StreamProperties };
|
|
|
|
function useVisibilityScopes(userId?: string, networkId?: string) {
|
|
return useMemo(() => {
|
|
const scopes: string[] = [];
|
|
if (userId) scopes.push(`human:${userId}`);
|
|
if (networkId) scopes.push(`network:${networkId}`);
|
|
return scopes;
|
|
}, [userId, networkId]);
|
|
}
|
|
|
|
interface UseStreamParticlesResult {
|
|
streams: StreamParticle[];
|
|
isLoading: boolean;
|
|
networkId: string;
|
|
}
|
|
|
|
export function useStreamParticles(path: ParticlePath): UseStreamParticlesResult {
|
|
const { networkId } = parseParticlePath(path);
|
|
const user = useAuthStore((s) => s.user);
|
|
const visibilityScopes = useVisibilityScopes(user?.id, networkId);
|
|
|
|
const [recencyCutoff, setRecencyCutoff] = useState(() => {
|
|
const d = new Date();
|
|
d.setHours(d.getHours() - RECENCY_WINDOW_HOURS);
|
|
return Timestamp.fromDate(d);
|
|
});
|
|
|
|
useEffect(() => {
|
|
const interval = setInterval(() => {
|
|
const d = new Date();
|
|
d.setHours(d.getHours() - RECENCY_WINDOW_HOURS);
|
|
setRecencyCutoff(Timestamp.fromDate(d));
|
|
}, 60 * 60 * 1000);
|
|
return () => clearInterval(interval);
|
|
}, []);
|
|
|
|
const { children, isLoading } = useLiveParticleChildren(
|
|
path,
|
|
"last_child_created_at",
|
|
"desc",
|
|
visibilityScopes,
|
|
undefined,
|
|
undefined,
|
|
where("last_child_created_at", ">=", recencyCutoff),
|
|
);
|
|
|
|
const streams = useMemo(
|
|
() => children.filter((c): c is StreamParticle => c.type === "stream"),
|
|
[children],
|
|
);
|
|
|
|
return { streams, isLoading, networkId };
|
|
}
|