"use client"; import { useEffect } from "react"; import { useRouter } from "next/navigation"; import { sse } from "@/lib/realtime/sse"; import { startRealtimeRefresh } from "@/lib/realtime/realtime-refresh"; type FormRealtimeRefreshProps = { topic: "forms" | "submissions"; formId?: string; debounceMs?: number; }; type UploadRealtimeRefreshProps = { topic: "uploads"; debounceMs?: number; }; type LeaderboardRealtimeRefreshProps = | { topic: "leaderboards"; leaderboard: "xp"; channelId?: never; debounceMs?: number; } | { topic: "leaderboards"; leaderboard: "vc"; channelId?: string; debounceMs?: number; } | { topic: "leaderboards"; leaderboard: "profile"; channelId?: never; debounceMs?: number; }; type RealtimeRefreshProps = | FormRealtimeRefreshProps | UploadRealtimeRefreshProps | LeaderboardRealtimeRefreshProps; export function RealtimeRefresh(props: RealtimeRefreshProps) { const router = useRouter(); const topic = props.topic; const formId = topic === "forms" || topic === "submissions" ? props.formId : undefined; const leaderboard = topic === "leaderboards" ? props.leaderboard : undefined; const channelId = topic === "leaderboards" ? props.channelId : undefined; const debounceMs = props.debounceMs ?? (topic === "leaderboards" ? 500 : 150); useEffect(() => { const filter = topic === "leaderboards" ? leaderboard === "profile" ? { kind: "profile" as const } : leaderboard === "xp" ? { kind: "xp" as const } : { kind: "vc" as const, channelId } : topic === "uploads" ? { kind: "uploads" as const } : { kind: "form" as const, formId }; return startRealtimeRefresh({ filter, debounceMs, refresh: () => router.refresh(), subscribe(emit) { const options = { onopen: () => emit({ kind: "open" }) }; if (topic === "forms") { return sse.forms.sub( "update", (event) => emit({ kind: "form", formId: event.formId }), options, ); } if (topic === "submissions") { return sse.submissions.sub( "update", (event) => emit({ kind: "form", formId: event.formId }), options, ); } if (topic === "uploads") { return sse.uploads.sub("update", () => emit({ kind: "upload" }), options); } return sse.leaderboards.subMany({ xp: () => emit({ kind: "xp" }), vc: (event) => emit({ kind: "vc", channelId: event.channelId }), }, options); }, }); }, [channelId, debounceMs, formId, leaderboard, router, topic]); return null; }