1
0
mirror of https://github.com/oceanprotocol/market.git synced 2024-12-02 05:57:29 +01:00

NFT image & faulty metadata fixes (#1779)

* safeguard against faults in metadata.tags

* properly handle image strings in tokenURI

* keep image ratios

* render test for faulty tags

* tweak fallback in popover
This commit is contained in:
Matthias Kretschmann 2022-11-09 12:22:30 +00:00 committed by GitHub
parent ee4e5c3b4d
commit 482af1be0c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 41 additions and 16 deletions

View File

@ -82,10 +82,13 @@ export function generateNftCreateData(
export function decodeTokenURI(tokenURI: string): NftMetadata { export function decodeTokenURI(tokenURI: string): NftMetadata {
if (!tokenURI) return undefined if (!tokenURI) return undefined
try { try {
const nftMeta = JSON.parse( const nftMeta = tokenURI.includes('data:application/json')
? (JSON.parse(
Buffer.from(tokenURI.replace(tokenUriPrefix, ''), 'base64').toString() Buffer.from(tokenURI.replace(tokenUriPrefix, ''), 'base64').toString()
) as NftMetadata ) as NftMetadata)
: ({ image: tokenURI } as NftMetadata)
return nftMeta return nftMeta
} catch (error) { } catch (error) {

View File

@ -69,11 +69,13 @@ export default function AssetList({
const styleClasses = `${styles.assetList} ${className || ''}` const styleClasses = `${styles.assetList} ${className || ''}`
return assetsWithPrices && !loading ? ( return loading ? (
<LoaderArea />
) : (
<> <>
<div className={styleClasses}> <div className={styleClasses}>
{assetsWithPrices.length > 0 ? ( {assetsWithPrices?.length > 0 ? (
assetsWithPrices.map((assetWithPrice) => ( assetsWithPrices?.map((assetWithPrice) => (
<AssetTeaser <AssetTeaser
asset={assetWithPrice} asset={assetWithPrice}
key={assetWithPrice.id} key={assetWithPrice.id}
@ -95,7 +97,5 @@ export default function AssetList({
/> />
)} )}
</> </>
) : (
<LoaderArea />
) )
} }

View File

@ -24,4 +24,9 @@ describe('Tags', () => {
it('renders WithoutLinks', () => { it('renders WithoutLinks', () => {
render(<Tags {...argsWithoutLinks} />) render(<Tags {...argsWithoutLinks} />)
}) })
it('renders with faulty tags', () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
render(<Tags items={'tags' as any} />)
})
}) })

View File

@ -30,6 +30,9 @@ export default function Tags({
className, className,
noLinks noLinks
}: TagsProps): ReactElement { }: TagsProps): ReactElement {
// safeguard against faults in the metadata
if (!(items instanceof Array)) return null
max = max || items.length max = max || items.length
const remainder = items.length - max const remainder = items.length - max
// filter out empty array items, and restrict to `max` // filter out empty array items, and restrict to `max`

View File

@ -7,7 +7,7 @@
.wrapper img { .wrapper img {
margin: 0; margin: 0;
width: 128px; width: 128px;
height: 128px; height: auto;
} }
.info { .info {

View File

@ -14,11 +14,13 @@ const openSeaTestNetworks = [4]
export default function NftTooltip({ export default function NftTooltip({
nft, nft,
nftImage,
address, address,
chainId, chainId,
isBlockscoutExplorer isBlockscoutExplorer
}: { }: {
nft: NftMetadata nft: NftMetadata
nftImage: string
address: string address: string
chainId: number chainId: number
isBlockscoutExplorer: boolean isBlockscoutExplorer: boolean
@ -39,7 +41,7 @@ export default function NftTooltip({
return ( return (
<div className={styles.wrapper}> <div className={styles.wrapper}>
{nft && <img src={nft.image_data || nft.image} alt={nft?.name} />} {nftImage && <img src={nftImage} alt={nft?.name} />}
<div className={styles.info}> <div className={styles.info}>
{nft && <h5>{nft.name}</h5>} {nft && <h5>{nft.name}</h5>}
{address && ( {address && (

View File

@ -4,14 +4,19 @@
border-right: 1px solid var(--border-color); border-right: 1px solid var(--border-color);
width: calc(var(--spacer) * 2); width: calc(var(--spacer) * 2);
height: calc(var(--spacer) * 2); height: calc(var(--spacer) * 2);
display: flex;
align-items: center;
} }
.nftImage img,
.nftImage > svg:first-of-type { .nftImage > svg:first-of-type {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
.nftImage img {
height: auto;
}
.nftImage > svg:first-of-type { .nftImage > svg:first-of-type {
transform: scale(0.7); transform: scale(0.7);
} }

View File

@ -48,6 +48,7 @@ export default function Nft({
content={ content={
<NftTooltip <NftTooltip
nft={nftMetadata} nft={nftMetadata}
nftImage={nftImage}
address={asset?.nftAddress} address={asset?.nftAddress}
chainId={asset?.chainId} chainId={asset?.chainId}
isBlockscoutExplorer={isBlockscoutExplorer} isBlockscoutExplorer={isBlockscoutExplorer}

View File

@ -31,11 +31,17 @@ export default function RelatedAssets(): ReactElement {
setIsLoading(true) setIsLoading(true)
try { try {
let tagResults: Asset[] = []
// safeguard against faults in the metadata
if (asset.metadata.tags instanceof Array) {
const tagQuery = generateBaseQuery( const tagQuery = generateBaseQuery(
generateQuery(chainIds, asset.nftAddress, 4, asset.metadata.tags) generateQuery(chainIds, asset.nftAddress, 4, asset.metadata.tags)
) )
const tagResults = (await queryMetadata(tagQuery, newCancelToken()))
tagResults = (await queryMetadata(tagQuery, newCancelToken()))
?.results ?.results
}
if (tagResults.length === 4) { if (tagResults.length === 4) {
setRelatedAssets(tagResults) setRelatedAssets(tagResults)