diff --git a/lib/components/base-auto-join-community-handler.react.js b/lib/components/base-auto-join-community-handler.react.js --- a/lib/components/base-auto-join-community-handler.react.js +++ b/lib/components/base-auto-join-community-handler.react.js @@ -4,7 +4,7 @@ import _pickBy from 'lodash/fp/pickBy.js'; import * as React from 'react'; -import { NeynarClientContext } from '../components/neynar-client-provider.react.js'; +import { NeynarClientContext } from './neynar-client-provider.react.js'; import blobService from '../facts/blob-service.js'; import { useIsLoggedInToIdentityAndAuthoritativeKeyserver } from '../hooks/account-hooks.js'; import { extractKeyserverIDFromID } from '../keyserver-conn/keyserver-call-utils.js'; diff --git a/lib/components/farcaster-channel-prefetch-handler.react.js b/lib/components/farcaster-channel-prefetch-handler.react.js new file mode 100644 --- /dev/null +++ b/lib/components/farcaster-channel-prefetch-handler.react.js @@ -0,0 +1,52 @@ +// @flow + +import * as React from 'react'; + +import { NeynarClientContext } from './neynar-client-provider.react.js'; +import { useIsLoggedInToIdentityAndAuthoritativeKeyserver } from '../hooks/account-hooks.js'; +import { useCurrentUserFID } from '../utils/farcaster-utils.js'; +import { useSelector } from '../utils/redux-utils.js'; + +// We want to use the following pattern to query for Farcaster channels when +// the app starts: +// - First, if the user has an FID, query for all of the channels they follow +// - Next, regardless of whether the user has an FID, query for all of the +// channels in the communityStore that are being used for avatars +// This pattern allows us to minimize the number of Neynar fetches to 1 or 2. +// For the second step, this component allows us to fetch in bulk, rather than +// fetching based on the pattern of ThreadAvatar component renders. +function FarcasterChannelPrefetchHandler(): React.Node { + const loggedIn = useIsLoggedInToIdentityAndAuthoritativeKeyserver(); + + const fcCache = React.useContext(NeynarClientContext)?.fcCache; + const fid = useCurrentUserFID(); + + const communityInfos = useSelector( + state => state.communityStore.communityInfos, + ); + + React.useEffect(() => { + if (!loggedIn || !fcCache) { + return; + } + + if (fid) { + void fcCache.getFollowedFarcasterChannelsForFID(fid); + } + + for (const communityID in communityInfos) { + const { farcasterChannelID } = communityInfos[communityID]; + if (farcasterChannelID) { + void fcCache.getFarcasterChannelForChannelID(farcasterChannelID); + } + } + // We only want this effect to run when loggedIn or fid change. Its purpose + // is to query for this info immediately so it can be done in bulk, so we + // don't care to rerun it when communityInfos or threadInfos change. + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [loggedIn, fid]); + + return null; +} + +export { FarcasterChannelPrefetchHandler }; diff --git a/native/root.react.js b/native/root.react.js --- a/native/root.react.js +++ b/native/root.react.js @@ -26,6 +26,7 @@ import { ChatMentionContextProvider } from 'lib/components/chat-mention-provider.react.js'; import { EditUserAvatarProvider } from 'lib/components/edit-user-avatar-provider.react.js'; import { ENSCacheProvider } from 'lib/components/ens-cache-provider.react.js'; +import { FarcasterChannelPrefetchHandler } from 'lib/components/farcaster-channel-prefetch-handler.react.js'; import { FarcasterDataHandler } from 'lib/components/farcaster-data-handler.react.js'; import { GlobalSearchIndexProvider } from 'lib/components/global-search-index-provider.react.js'; import IntegrityHandler from 'lib/components/integrity-handler.react.js'; @@ -393,6 +394,7 @@ + diff --git a/web/app.react.js b/web/app.react.js --- a/web/app.react.js +++ b/web/app.react.js @@ -15,6 +15,7 @@ } from 'lib/actions/entry-actions.js'; import { ChatMentionContextProvider } from 'lib/components/chat-mention-provider.react.js'; import { EditUserAvatarProvider } from 'lib/components/edit-user-avatar-provider.react.js'; +import { FarcasterChannelPrefetchHandler } from 'lib/components/farcaster-channel-prefetch-handler.react.js'; import { FarcasterDataHandler } from 'lib/components/farcaster-data-handler.react.js'; import { GlobalSearchIndexProvider } from 'lib/components/global-search-index-provider.react.js'; import { @@ -259,6 +260,7 @@ +