import { useQuery } from '@tanstack/react-query'; import { SKATE_SKATER_KIND, SKATER_TAG, parseSkater, type Skater } from '@/lib/types'; import { useSkateRelays } from '@/hooks/useSkateRelays'; import { useAdminModeration, filterAdminHidden } from '@/hooks/useAdminModeration'; const SKATER_D = 'skater-profile'; /** * List all SkateSpots skater profiles (kind 35000, tagged skateskater). * Queried from the skate relays only — this is the anti-spam boundary: * plain kind-0 Nostr profiles never appear here, only opted-in app skaters. * Deduplicated per author (newest wins), newest-first. */ export function useSkaters(limit = 200) { const { querySkateContent, getQueryKeySuffix } = useSkateRelays(); const hidden = useAdminModeration(); return useQuery({ queryKey: ['skaters', limit, getQueryKeySuffix()], select: (skaters: Skater[]) => filterAdminHidden(skaters, SKATE_SKATER_KIND, hidden), queryFn: async () => { const signal = AbortSignal.timeout(10000); const events = await querySkateContent( [{ kinds: [SKATE_SKATER_KIND], '#t': [SKATER_TAG], limit }], { signal }, ); // Deduplicate: keep the newest profile per author. const byAuthor = new Map(); for (const event of events) { const s = parseSkater(event); if (!s) continue; const existing = byAuthor.get(s.pubkey); if (!existing || s.createdAt > existing.createdAt) byAuthor.set(s.pubkey, s); } return [...byAuthor.values()].sort((a, b) => b.createdAt - a.createdAt); }, staleTime: 30000, refetchOnMount: 'always', }); } /** Fetch a single user's skater profile (or null). */ export function useUserSkaterProfile(pubkey: string | undefined) { const { querySkateContent, getQueryKeySuffix } = useSkateRelays(); return useQuery({ queryKey: ['skater-profile', pubkey, getQueryKeySuffix()], enabled: !!pubkey, queryFn: async () => { if (!pubkey) return null; const signal = AbortSignal.timeout(10000); const events = await querySkateContent( [{ kinds: [SKATE_SKATER_KIND], authors: [pubkey], '#d': [SKATER_D], limit: 1 }], { signal }, ); if (events.length === 0) return null; return parseSkater(events[0]); }, staleTime: 30000, refetchOnMount: 'always', }); } export { SKATER_D };