diff --git a/lib/shared/avatar-utils.js b/lib/shared/avatar-utils.js --- a/lib/shared/avatar-utils.js +++ b/lib/shared/avatar-utils.js @@ -9,7 +9,10 @@ import { threadOtherMembers } from './thread-utils.js'; import genesis from '../facts/genesis.js'; import { useENSAvatar } from '../hooks/ens-cache.js'; -import { useFarcasterUserAvatarURL } from '../hooks/fc-cache.js'; +import { + useFarcasterUserAvatarURL, + useFarcasterChannelAvatarURL, +} from '../hooks/fc-cache.js'; import type { ClientAvatar, ClientEmojiAvatar, @@ -319,9 +322,12 @@ return getDefaultAvatar(thread.id, thread.color); } +type UsernameAndFID = { +username?: ?string, +farcasterID: ?string, ... }; +type FCChannelInfo = { +fcChannelID: ?string }; + function useResolvedUserAvatar( userAvatarInfo: ClientAvatar, - usernameAndFID: ?{ +username?: ?string, +farcasterID?: ?string, ... }, + usernameAndFID: ?UsernameAndFID, ): ResolvedClientAvatar { const ethAddress = React.useMemo( () => getETHAddressForUserInfo(usernameAndFID), @@ -338,12 +344,14 @@ return userAvatarInfo; } - if (ensAvatarURI) { + if (ensAvatarURI && userAvatarInfo.type === 'ens') { return { type: 'image', uri: ensAvatarURI, }; - } else if (farcasterAvatarURL) { + } + + if (farcasterAvatarURL && userAvatarInfo.type === 'farcaster') { return { type: 'image', uri: farcasterAvatarURL, @@ -358,12 +366,20 @@ function useResolvedThreadAvatar( threadAvatarInfo: ClientAvatar, - displayUser: ?{ +username?: ?string, +farcasterID?: ?string, ... }, + params: { + +userProfileInfo: ?UsernameAndFID, + +channelInfo: FCChannelInfo, + }, ): ResolvedClientAvatar { - const resolvedUserAvatar = useResolvedUserAvatar( - threadAvatarInfo, - displayUser, - ); + const username = params.userProfileInfo?.username; + const farcasterID = params.userProfileInfo?.farcasterID; + const fcChannelID = params.channelInfo.fcChannelID; + + const resolvedUserAvatar = useResolvedUserAvatar(threadAvatarInfo, { + username, + farcasterID, + }); + const farcasterAvatarURL = useFarcasterChannelAvatarURL(fcChannelID); if ( threadAvatarInfo.type !== 'ens' && @@ -372,7 +388,24 @@ return threadAvatarInfo; } - return resolvedUserAvatar; + // If both `userProfileInfo` and `channelInfo` are supplied, the former should + // supersede the latter. + if (username || farcasterID) { + return resolvedUserAvatar; + } + + if (farcasterAvatarURL) { + return { + type: 'image', + uri: farcasterAvatarURL, + }; + } + + return { + type: 'emoji', + color: selectedThreadColors[4], + emoji: '👥', + }; } export { diff --git a/native/avatars/thread-avatar.react.js b/native/avatars/thread-avatar.react.js --- a/native/avatars/thread-avatar.react.js +++ b/native/avatars/thread-avatar.react.js @@ -55,7 +55,10 @@ }; }); - const resolvedThreadAvatar = useResolvedThreadAvatar(avatarInfo, displayUser); + const resolvedThreadAvatar = useResolvedThreadAvatar(avatarInfo, { + userProfileInfo: displayUser, + channelInfo: { fcChannelID: null }, + }); return ; } diff --git a/web/avatars/thread-avatar.react.js b/web/avatars/thread-avatar.react.js --- a/web/avatars/thread-avatar.react.js +++ b/web/avatars/thread-avatar.react.js @@ -55,7 +55,10 @@ }; }); - const resolvedThreadAvatar = useResolvedThreadAvatar(avatarInfo, displayUser); + const resolvedThreadAvatar = useResolvedThreadAvatar(avatarInfo, { + userProfileInfo: displayUser, + channelInfo: { fcChannelID: null }, + }); return (