Live video on the AT Protocol
1import { ProfileViewDetailed } from "@atproto/api/dist/client/types/app/bsky/actor/defs";
2import { useEffect, useMemo, useRef, useState } from "react";
3import { usePDSAgent } from "../streamplace-store/xrpc";
4
5export function useAvatars(
6 dids: string[],
7): Record<string, ProfileViewDetailed> {
8 let agent = usePDSAgent();
9 const [profiles, setProfiles] = useState<Record<string, ProfileViewDetailed>>(
10 {},
11 );
12 const inFlight = useRef<Set<string>>(new Set());
13
14 const missingDids = useMemo(
15 () =>
16 dids.filter((did) => !(did in profiles) && !inFlight.current.has(did)),
17 [dids, profiles],
18 );
19
20 useEffect(() => {
21 if (missingDids.length === 0 || !agent) return;
22 const toFetch = missingDids.slice(0, 25);
23 toFetch.forEach((did) => inFlight.current.add(did));
24
25 const fetchProfiles = async () => {
26 try {
27 const result = await agent.getProfiles({ actors: toFetch });
28 const newProfiles: Record<string, ProfileViewDetailed> = {};
29 result.data.profiles.forEach((p) => {
30 newProfiles[p.did] = p;
31 });
32 setProfiles((prev) => ({ ...prev, ...newProfiles }));
33 } catch (e) {
34 console.error("Failed to fetch profiles", e);
35 } finally {
36 toFetch.forEach((did) => inFlight.current.delete(did));
37 }
38 };
39
40 fetchProfiles();
41 }, [missingDids, agent]);
42
43 return profiles;
44}