diff --git a/src/components/AppBar/AppBar.tsx b/src/components/AppBar/AppBar.tsx index 4176a42..495e9dc 100644 --- a/src/components/AppBar/AppBar.tsx +++ b/src/components/AppBar/AppBar.tsx @@ -28,9 +28,9 @@ import { } from '../../routes' import { clearAuthToken, + getProfileUsername, hexToNpub, - saveNsecBunkerDelegatedKey, - shorten + saveNsecBunkerDelegatedKey } from '../../utils' import styles from './style.module.scss' import { setUserRobotImage } from '../../store/userRobotImage/action' @@ -58,9 +58,8 @@ export const AppBar = () => { useEffect(() => { if (metadataState) { if (metadataState.content) { - const { picture, display_name, name } = JSON.parse( - metadataState.content - ) + const profileMetadata = JSON.parse(metadataState.content) + const { picture } = profileMetadata if (picture || userRobotImage) { setUserAvatar(picture || userRobotImage) @@ -70,7 +69,7 @@ export const AppBar = () => { ? hexToNpub(authState.usersPubkey) : '' - setUsername(shorten(display_name || name || npub, 7)) + setUsername(getProfileUsername(npub, profileMetadata)) } else { setUserAvatar(userRobotImage || '') setUsername('') diff --git a/src/components/UserAvatar/index.tsx b/src/components/UserAvatar/index.tsx index 0ea1fc1..4c49e33 100644 --- a/src/components/UserAvatar/index.tsx +++ b/src/components/UserAvatar/index.tsx @@ -5,7 +5,7 @@ import { AvatarIconButton } from '../UserAvatarIconButton' import { Link } from 'react-router-dom' import { useProfileMetadata } from '../../hooks/useProfileMetadata' import { Tooltip } from '@mui/material' -import { shorten } from '../../utils' +import { getProfileUsername } from '../../utils' import { TooltipChild } from '../TooltipChild' interface UserAvatarProps { @@ -22,7 +22,7 @@ export const UserAvatar = ({ isNameVisible = false }: UserAvatarProps) => { const profile = useProfileMetadata(pubkey) - const name = profile?.display_name || profile?.name || shorten(pubkey) + const name = getProfileUsername(pubkey, profile) const image = profile?.picture return ( diff --git a/src/pages/profile/index.tsx b/src/pages/profile/index.tsx index 905e7d0..4405f1f 100644 --- a/src/pages/profile/index.tsx +++ b/src/pages/profile/index.tsx @@ -1,7 +1,6 @@ import ContentCopyIcon from '@mui/icons-material/ContentCopy' import EditIcon from '@mui/icons-material/Edit' import { Box, IconButton, SxProps, Theme, Typography } from '@mui/material' -import { truncate } from 'lodash' import { Event, VerifiedEvent, kinds, nip19 } from 'nostr-tools' import { useEffect, useMemo, useState } from 'react' import { useSelector } from 'react-redux' @@ -14,6 +13,7 @@ import { State } from '../../store/rootReducer' import { NostrJoiningBlock, ProfileMetadata } from '../../types' import { getNostrJoiningBlockNumber, + getProfileUsername, getRoboHashPicture, hexToNpub, shorten @@ -42,15 +42,7 @@ export const ProfilePage = () => { const [isLoading, setIsLoading] = useState(true) const [loadingSpinnerDesc] = useState('Fetching metadata') - const profileName = - pubkey && - profileMetadata && - truncate( - profileMetadata.display_name || profileMetadata.name || hexToNpub(pubkey), - { - length: 16 - } - ) + const profileName = pubkey && getProfileUsername(pubkey, profileMetadata) useEffect(() => { if (npub) { diff --git a/src/types/profile.ts b/src/types/profile.ts index 122fbf6..1dcfa6f 100644 --- a/src/types/profile.ts +++ b/src/types/profile.ts @@ -1,6 +1,7 @@ export interface ProfileMetadata { name?: string display_name?: string + /** @deprecated use name instead */ username?: string picture?: string banner?: string diff --git a/src/utils/nostr.ts b/src/utils/nostr.ts index ec42325..1082328 100644 --- a/src/utils/nostr.ts +++ b/src/utils/nostr.ts @@ -1,6 +1,6 @@ import { bytesToHex, hexToBytes } from '@noble/hashes/utils' import axios from 'axios' -import _ from 'lodash' +import _, { truncate } from 'lodash' import { Event, EventTemplate, @@ -30,7 +30,7 @@ import { import { AuthState, Keys } from '../store/auth/types' import { RelaysState } from '../store/relays/types' import store from '../store/store' -import { Meta, SignedEvent, UserAppData } from '../types' +import { Meta, ProfileMetadata, SignedEvent, UserAppData } from '../types' import { getDefaultRelayMap } from './relays' import { parseJson, removeLeadingSlash } from './string' import { timeout } from './utils' @@ -974,3 +974,16 @@ export const sendNotification = async (receiver: string, meta: Meta) => { throw err }) } + +/** + * Show user's name, first available in order: display_name, name, or npub as fallback + * @param userId User identifier, it can be either pubkey or npub1 (we only show npub) + * @param profile User profile + */ +export const getProfileUsername = ( + userId: `npub1${string}` | string, + profile?: ProfileMetadata +) => + truncate(profile?.display_name || profile?.name || hexToNpub(userId), { + length: 16 + })