diff --git a/lib/types/user-types.js b/lib/types/user-types.js --- a/lib/types/user-types.js +++ b/lib/types/user-types.js @@ -34,12 +34,14 @@ export type UserInfo = { +id: string, +username: ?string, + +farcasterUsername?: ?string, +relationshipStatus?: UserRelationshipStatus, +avatar?: ?ClientAvatar, }; export const userInfoValidator: TInterface = tShape({ id: tUserID, username: t.maybe(t.String), + farcasterUsername: t.maybe(t.String), relationshipStatus: t.maybe(userRelationshipStatusValidator), avatar: t.maybe(clientAvatarValidator), }); diff --git a/native/user-profile/user-profile.react.js b/native/user-profile/user-profile.react.js --- a/native/user-profile/user-profile.react.js +++ b/native/user-profile/user-profile.react.js @@ -6,10 +6,14 @@ import { View, Text, TouchableOpacity } from 'react-native'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; -import { useResolvedUsername } from 'lib/hooks/ens-cache.js'; +import { useResolvableNames } from 'lib/hooks/ens-cache.js'; import { relationshipBlockedInEitherDirection } from 'lib/shared/relationship-utils.js'; import { useUserProfileThreadInfo } from 'lib/shared/thread-utils.js'; -import type { UserInfo } from 'lib/types/user-types'; +import { + stringForUserExplicit, + ensNameForFarcasterUsername, +} from 'lib/shared/user-utils.js'; +import type { UserInfo } from 'lib/types/user-types.js'; import sleep from 'lib/utils/sleep.js'; import UserProfileAvatar from './user-profile-avatar.react.js'; @@ -35,7 +39,32 @@ const userProfileThreadInfo = useUserProfileThreadInfo(userInfo); - const resolvedUsernameText = useResolvedUsername(userInfo); + const [resolvedUserInfo] = useResolvableNames([userInfo]); + const resolvedUsernameText = stringForUserExplicit(resolvedUserInfo); + + const farcasterUsername = resolvedUserInfo?.farcasterUsername; + + const styles = useStyles(unboundStyles); + + const farcasterUsernameElement = React.useMemo(() => { + if (!farcasterUsername) { + return null; + } + const ensFCName = ensNameForFarcasterUsername(farcasterUsername); + if (ensFCName === resolvedUsernameText) { + return null; + } + return ( + + Farcaster: {ensFCName} + + ); + }, [ + farcasterUsername, + resolvedUsernameText, + styles.farcasterUsernameText, + styles.farcasterUsernameContainer, + ]); const [usernameCopied, setUsernameCopied] = React.useState(false); @@ -76,8 +105,6 @@ userProfileThreadInfo, ]); - const styles = useStyles(unboundStyles); - const menuButton = React.useMemo(() => { if (!userProfileThreadInfo) { return null; @@ -177,6 +204,7 @@ {resolvedUsernameText} {copyUsernameButton} + {farcasterUsernameElement} {messageButton} @@ -203,6 +231,14 @@ fontSize: 18, fontWeight: '500', }, + farcasterUsernameContainer: { + paddingVertical: 8, + }, + farcasterUsernameText: { + color: 'modalForegroundLabel', + fontSize: 14, + fontWeight: '500', + }, copyUsernameContainer: { flexDirection: 'row', justifyContent: 'center',