diff --git a/lib/hooks/fc-cache.js b/lib/hooks/fc-cache.js index dfc9eccd4..df439f959 100644 --- a/lib/hooks/fc-cache.js +++ b/lib/hooks/fc-cache.js @@ -1,144 +1,144 @@ // @flow import * as React from 'react'; import { NeynarClientContext } from '../components/neynar-client-provider.react.js'; import { getFCNames } from '../utils/farcaster-helpers.js'; type BaseFCInfo = { +fid?: ?string, +farcasterUsername?: ?string, ... }; export type UseFCNamesOptions = { +allAtOnce?: ?boolean, }; function useFCNames( users: $ReadOnlyArray, options?: ?UseFCNamesOptions, ): T[] { const neynarClientContext = React.useContext(NeynarClientContext); const fcCache = neynarClientContext?.fcCache; const allAtOnce = options?.allAtOnce ?? false; const cachedInfo = React.useMemo( () => users.map(user => { if (!user) { return user; } const { fid, farcasterUsername } = user; let cachedResult = null; if (farcasterUsername) { cachedResult = farcasterUsername; } else if (fid && fcCache) { - cachedResult = fcCache.getCachedFarcasterUserForFID(fid); + cachedResult = fcCache.getCachedFarcasterUserForFID(fid)?.username; } return { input: user, fid, cachedResult, }; }), [users, fcCache], ); const [fetchedFIDs, setFetchedFIDs] = React.useState<$ReadOnlySet>( new Set(), ); const [farcasterUsernames, setFarcasterUsernames] = React.useState< $ReadOnlyMap, >(new Map()); React.useEffect(() => { if (!fcCache) { return; } const needFetchUsers: $ReadOnlyArray<{ +fid: string, +farcasterUsername?: ?string, }> = cachedInfo .map(user => { if (!user) { return null; } const { fid, cachedResult } = user; if (cachedResult || !fid || fetchedFIDs.has(fid)) { return null; } return { fid }; }) .filter(Boolean); if (needFetchUsers.length === 0) { return; } const needFetchFIDs = needFetchUsers.map(({ fid }) => fid); setFetchedFIDs(oldFetchedFIDs => { const newFetchedFIDs = new Set(oldFetchedFIDs); for (const fid of needFetchFIDs) { newFetchedFIDs.add(fid); } return newFetchedFIDs; }); if (allAtOnce) { void (async () => { const withFarcasterUsernames = await getFCNames( fcCache, needFetchUsers, ); setFarcasterUsernames(oldFarcasterUsernames => { const newFarcasterUsernames = new Map(oldFarcasterUsernames); for (let i = 0; i < withFarcasterUsernames.length; i++) { const fid = needFetchFIDs[i]; const result = withFarcasterUsernames[i].farcasterUsername; if (result) { newFarcasterUsernames.set(fid, result); } } return newFarcasterUsernames; }); })(); return; } for (const fid of needFetchFIDs) { void (async () => { const [result] = await fcCache.getFarcasterUsersForFIDs([fid]); if (!result) { return; } setFarcasterUsernames(oldFarcasterUsernames => { const newFarcasterUsernames = new Map(oldFarcasterUsernames); newFarcasterUsernames.set(fid, result.username); return newFarcasterUsernames; }); })(); } }, [cachedInfo, fetchedFIDs, fcCache, allAtOnce]); return React.useMemo( () => cachedInfo.map(user => { if (!user) { return user; } const { input, fid, cachedResult } = user; if (cachedResult) { return { ...input, farcasterUsername: cachedResult }; } else if (!fid) { return input; } const farcasterUsername = farcasterUsernames.get(fid); if (farcasterUsername) { return { ...input, farcasterUsername }; } return input; }), [cachedInfo, farcasterUsernames], ); } export { useFCNames };