Placeholder avatar is incosistent across components #39

Merged
s merged 9 commits from issue-27 into main 2024-05-16 08:58:11 +00:00
5 changed files with 30 additions and 17 deletions
Showing only changes of commit 4f4f7fb5c1 - Show all commits

View File

@ -16,11 +16,12 @@ import { Dispatch } from '../../store/store'
import Username from '../username' import Username from '../username'
import { Link, useNavigate } from 'react-router-dom' import { Link, useNavigate } from 'react-router-dom'
import nostrichAvatar from '../../assets/images/avatar.png'
import { NostrController } from '../../controllers' import { NostrController } from '../../controllers'
import { appPublicRoutes, getProfileRoute } from '../../routes' import { appPublicRoutes, getProfileRoute } from '../../routes'
import { import {
clearAuthToken, clearAuthToken,
getRoboHashPicture,
hexToNpub,
saveNsecBunkerDelegatedKey, saveNsecBunkerDelegatedKey,
shorten shorten
} from '../../utils' } from '../../utils'
@ -32,7 +33,7 @@ export const AppBar = () => {
const dispatch: Dispatch = useDispatch() const dispatch: Dispatch = useDispatch()
const [username, setUsername] = useState('') const [username, setUsername] = useState('')
const [userAvatar, setUserAvatar] = useState(nostrichAvatar) const [userAvatar, setUserAvatar] = useState('')
const [anchorElUser, setAnchorElUser] = useState<null | HTMLElement>(null) const [anchorElUser, setAnchorElUser] = useState<null | HTMLElement>(null)
const authState = useSelector((state: State) => state.auth) const authState = useSelector((state: State) => state.auth)
@ -41,8 +42,13 @@ export const AppBar = () => {
useEffect(() => { useEffect(() => {
if (metadataState && metadataState.content) { if (metadataState && metadataState.content) {
const { picture, display_name, name } = JSON.parse(metadataState.content) const { picture, display_name, name } = JSON.parse(metadataState.content)
const npub = authState?.usersPubkey ? hexToNpub(authState.usersPubkey) : ''
if (picture) setUserAvatar(picture) if (picture) {
setUserAvatar(picture)
} else {
setUserAvatar(getRoboHashPicture(npub))
}
setUsername(shorten(display_name || name || '', 7)) setUsername(shorten(display_name || name || '', 7))
} }

View File

@ -21,7 +21,6 @@ import {
import { MuiFileInput } from 'mui-file-input' import { MuiFileInput } from 'mui-file-input'
import { useEffect, useState } from 'react' import { useEffect, useState } from 'react'
import { Link, useNavigate } from 'react-router-dom' import { Link, useNavigate } from 'react-router-dom'
import placeholderAvatar from '../../assets/images/avatar.png'
import { LoadingSpinner } from '../../components/LoadingSpinner' import { LoadingSpinner } from '../../components/LoadingSpinner'
import { MetadataController, NostrController } from '../../controllers' import { MetadataController, NostrController } from '../../controllers'
import { appPrivateRoutes, getProfileRoute } from '../../routes' import { appPrivateRoutes, getProfileRoute } from '../../routes'
@ -30,6 +29,7 @@ import {
encryptArrayBuffer, encryptArrayBuffer,
generateEncryptionKey, generateEncryptionKey,
getHash, getHash,
getRoboHashPicture,
hexToNpub, hexToNpub,
pubToHex, pubToHex,
queryNip05, queryNip05,
@ -489,8 +489,9 @@ const DisplayUser = ({
}) })
}, [users]) }, [users])
const imageLoadError = (event: any) => { const imageLoadError = (event: any, pubkey: string) => {
event.target.src = placeholderAvatar const npub = hexToNpub(pubkey)
event.target.src = getRoboHashPicture(npub)
} }
return ( return (
@ -513,7 +514,7 @@ const DisplayUser = ({
<TableCell className={styles.tableCell}> <TableCell className={styles.tableCell}>
<Box className={styles.user}> <Box className={styles.user}>
<img <img
onError={imageLoadError} onError={(event) => {imageLoadError(event, user.pubkey)}}
src={userMeta?.picture || roboUrl} src={userMeta?.picture || roboUrl}
alt="Profile Image" alt="Profile Image"
className="profile-image" className="profile-image"

View File

@ -15,7 +15,6 @@ import { UnsignedEvent, nip19, kinds, VerifiedEvent } from 'nostr-tools'
import { useEffect, useMemo, useState } from 'react' import { useEffect, useMemo, useState } from 'react'
import { Link, useParams } from 'react-router-dom' import { Link, useParams } from 'react-router-dom'
import { toast } from 'react-toastify' import { toast } from 'react-toastify'
import placeholderAvatar from '../../assets/images/avatar.png'
import { MetadataController, NostrController } from '../../controllers' import { MetadataController, NostrController } from '../../controllers'
import { NostrJoiningBlock, ProfileMetadata } from '../../types' import { NostrJoiningBlock, ProfileMetadata } from '../../types'
import styles from './style.module.scss' import styles from './style.module.scss'
@ -27,6 +26,7 @@ import { setMetadataEvent } from '../../store/actions'
import { LoadingSpinner } from '../../components/LoadingSpinner' import { LoadingSpinner } from '../../components/LoadingSpinner'
import { LoginMethods } from '../../store/auth/types' import { LoginMethods } from '../../store/auth/types'
import { SmartToy } from '@mui/icons-material' import { SmartToy } from '@mui/icons-material'
import { getRoboHashPicture } from '../../utils'
export const ProfilePage = () => { export const ProfilePage = () => {
const theme = useTheme() const theme = useTheme()
@ -282,13 +282,13 @@ export const ProfilePage = () => {
> >
<img <img
onError={(event: any) => { onError={(event: any) => {
event.target.src = placeholderAvatar event.target.src = npub ? getRoboHashPicture(npub) : ''
}} }}
onLoad={() => { onLoad={() => {
setAvatarLoading(false) setAvatarLoading(false)
}} }}
className={styles.img} className={styles.img}
src={profileMetadata.picture || placeholderAvatar} src={profileMetadata.picture || npub ? getRoboHashPicture(npub!) : ''}
alt="Profile Image" alt="Profile Image"
/> />

View File

@ -23,7 +23,6 @@ import { useEffect, useState } from 'react'
import { useSelector } from 'react-redux' import { useSelector } from 'react-redux'
import { Link, useSearchParams } from 'react-router-dom' import { Link, useSearchParams } from 'react-router-dom'
import { toast } from 'react-toastify' import { toast } from 'react-toastify'
import placeholderAvatar from '../../assets/images/avatar.png'
import { LoadingSpinner } from '../../components/LoadingSpinner' import { LoadingSpinner } from '../../components/LoadingSpinner'
import { MetadataController, NostrController } from '../../controllers' import { MetadataController, NostrController } from '../../controllers'
import { getProfileRoute } from '../../routes' import { getProfileRoute } from '../../routes'
@ -34,6 +33,7 @@ import {
encryptArrayBuffer, encryptArrayBuffer,
generateEncryptionKey, generateEncryptionKey,
getHash, getHash,
getRoboHashPicture,
hexToNpub, hexToNpub,
parseJson, parseJson,
readContentOfZipEntry, readContentOfZipEntry,
@ -626,13 +626,14 @@ const DisplayMeta = ({ meta, nextSigner }: DisplayMetaProps) => {
}) })
}, [users, meta.submittedBy]) }, [users, meta.submittedBy])
const imageLoadError = (event: any) => { const imageLoadError = (event: any, pubkey: string) => {
event.target.src = placeholderAvatar const npub = hexToNpub(pubkey)
event.target.src = npub
} }
const getRoboImageUrl = (pubkey: string) => { const getRoboImageUrl = (pubkey: string) => {
const npub = hexToNpub(pubkey) const npub = hexToNpub(pubkey)
return `https://robohash.org/${npub}.png?set=set3` return getRoboHashPicture(npub)
} }
return ( return (
@ -666,7 +667,7 @@ const DisplayMeta = ({ meta, nextSigner }: DisplayMetaProps) => {
</Typography> </Typography>
<Box className={styles.user}> <Box className={styles.user}>
<img <img
onError={imageLoadError} onError={(event) => {imageLoadError(event, meta.submittedBy)}}
src={ src={
metadata[meta.submittedBy]?.picture || metadata[meta.submittedBy]?.picture ||
getRoboImageUrl(meta.submittedBy) getRoboImageUrl(meta.submittedBy)
@ -719,7 +720,7 @@ const DisplayMeta = ({ meta, nextSigner }: DisplayMetaProps) => {
{users.map((user, index) => { {users.map((user, index) => {
const userMeta = metadata[user.pubkey] const userMeta = metadata[user.pubkey]
const npub = hexToNpub(user.pubkey) const npub = hexToNpub(user.pubkey)
const roboUrl = `https://robohash.org/${npub}.png?set=set3` const roboUrl = getRoboHashPicture(npub)
let signedStatus = '-' let signedStatus = '-'
@ -739,7 +740,7 @@ const DisplayMeta = ({ meta, nextSigner }: DisplayMetaProps) => {
<TableCell className={styles.tableCell}> <TableCell className={styles.tableCell}>
<Box className={styles.user}> <Box className={styles.user}>
<img <img
onError={imageLoadError} onError={(event) => {imageLoadError(event, meta.submittedBy)}}
src={userMeta?.picture || roboUrl} src={userMeta?.picture || roboUrl}
alt="Profile Image" alt="Profile Image"
className="profile-image" className="profile-image"

View File

@ -58,6 +58,7 @@ export const nsecToHex = (nsec: string): string | null => {
export const hexToNpub = (hexPubkey: string | undefined): string => { export const hexToNpub = (hexPubkey: string | undefined): string => {
if (!hexPubkey) return 'n/a' if (!hexPubkey) return 'n/a'
if (hexPubkey.includes('npub')) return hexPubkey
return nip19.npubEncode(hexPubkey) return nip19.npubEncode(hexPubkey)
} }
@ -138,3 +139,7 @@ export const base64DecodeAuthToken = (authToken: string): SignedEvent => {
throw new Error('An error occurred in JSON.parse of the auth token') throw new Error('An error occurred in JSON.parse of the auth token')
} }
} }
export const getRoboHashPicture = (npub: string): string => {
return `https://robohash.org/${npub}.png?set=set3`
}