mirror of
https://github.com/oceanprotocol/market.git
synced 2024-12-02 05:57:29 +01:00
Feat: Display NFT in asset details (#1125)
* feat: add decodeTokenUri helper
* refactor: restructure of MetaMain component
* feat: add nft tooltip
* feat: add opensea link for nfts
* style: adjust nft image size in tooltip
* feat: add nft data to publish preview
* fix: readd owner to nft metadata
* refactor: conditional display of nft tooltip
* style: fix link styles in nft tooltip
* feat: add placeholder graphic as fallback if nft data does not contain one
* fix: display openSea link only on supported networks
* fix: rename ddo props to asset in metamain related components
* feat: add original publisher to asset details
* chore: remove unused imports
* fix: remove unused prop
* feat: convert publisher address to checksum address
* chore: remove console.error when decoding tokenURI
* Revert "chore: remove console.error when decoding tokenURI"
This reverts commit f387175970
.
* feat: shorten nft address in tooltip preview
* fix: use Web3.utils instead of the actual web3 instance to convert wei in ether
Co-authored-by: Luca Milanese <luca.milanese90@gmail.com>
Co-authored-by: Matthias Kretschmann <m@kretschmann.io>
This commit is contained in:
parent
8b331c0a63
commit
9d1b7794a3
@ -1,13 +1,13 @@
|
||||
import { SvgWaves } from './SvgWaves'
|
||||
import {
|
||||
Asset,
|
||||
LoggerInstance,
|
||||
Asset,
|
||||
getHash,
|
||||
Nft,
|
||||
ProviderInstance,
|
||||
DDO,
|
||||
MetadataAndTokenURI
|
||||
} from '@oceanprotocol/lib'
|
||||
import { SvgWaves } from './SvgWaves'
|
||||
import Web3 from 'web3'
|
||||
import { TransactionReceipt } from 'web3-core'
|
||||
|
||||
@ -60,6 +60,8 @@ export function generateNftMetadata(): NftMetadata {
|
||||
return newNft
|
||||
}
|
||||
|
||||
const tokenUriPrefix = 'data:application/json;base64,'
|
||||
|
||||
export function generateNftCreateData(nftMetadata: NftMetadata): any {
|
||||
const nftCreateData = {
|
||||
name: nftMetadata.name,
|
||||
@ -71,6 +73,19 @@ export function generateNftCreateData(nftMetadata: NftMetadata): any {
|
||||
return nftCreateData
|
||||
}
|
||||
|
||||
export function decodeTokenURI(tokenURI: string): NftMetadata {
|
||||
if (!tokenURI) return undefined
|
||||
try {
|
||||
const nftMeta = JSON.parse(
|
||||
Buffer.from(tokenURI.replace(tokenUriPrefix, ''), 'base64').toString()
|
||||
) as NftMetadata
|
||||
|
||||
return nftMeta
|
||||
} catch (error) {
|
||||
LoggerInstance.error(`[NFT] ${error.message}`)
|
||||
}
|
||||
}
|
||||
|
||||
export async function setNftMetadata(
|
||||
asset: Asset | DDO,
|
||||
accountId: string,
|
||||
|
@ -1,6 +1,7 @@
|
||||
import React, { ReactElement, useEffect, useState } from 'react'
|
||||
import { usePrices } from '@context/Prices'
|
||||
import { useWeb3 } from '@context/Web3'
|
||||
import Web3 from 'web3'
|
||||
import useNftFactory from '@hooks/contracts/useNftFactory'
|
||||
import { NftFactory } from '@oceanprotocol/lib'
|
||||
import Conversion from '@shared/Price/Conversion'
|
||||
@ -20,7 +21,7 @@ const getEstGasFee = async (
|
||||
|
||||
const gasPrice = await web3.eth.getGasPrice()
|
||||
const gasLimit = await nftFactory?.estGasCreateNFT(address, nft)
|
||||
const gasFeeEth = web3.utils.fromWei(
|
||||
const gasFeeEth = Web3.utils.fromWei(
|
||||
(+gasPrice * +gasLimit).toString(),
|
||||
'ether'
|
||||
)
|
||||
|
@ -6,7 +6,6 @@
|
||||
background: none;
|
||||
padding: 0;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.icon {
|
||||
@ -25,11 +24,12 @@
|
||||
fill: var(--brand-alert-green);
|
||||
}
|
||||
|
||||
.copied::after {
|
||||
content: 'Copied!';
|
||||
position: absolute;
|
||||
top: -150%;
|
||||
left: -140%;
|
||||
.action {
|
||||
display: flex;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
.feedback {
|
||||
font-size: var(--font-size-mini);
|
||||
color: var(--brand-alert-green);
|
||||
}
|
||||
|
@ -27,7 +27,10 @@ export default function Copy({ text }: { text: string }): ReactElement {
|
||||
onSuccess={() => setIsCopied(true)}
|
||||
className={`${styles.button} ${isCopied ? styles.copied : ''}`}
|
||||
>
|
||||
<IconCopy className={styles.icon} />
|
||||
<div className={styles.action}>
|
||||
<IconCopy className={styles.icon} />
|
||||
{isCopied && <span className={styles.feedback}>Copied!</span>}
|
||||
</div>
|
||||
</Clipboard>
|
||||
)
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ const getReceipts = gql`
|
||||
id
|
||||
nft {
|
||||
address
|
||||
owner
|
||||
}
|
||||
tx
|
||||
timestamp
|
||||
@ -25,7 +26,13 @@ const getReceipts = gql`
|
||||
}
|
||||
`
|
||||
|
||||
export default function EditHistory(): ReactElement {
|
||||
export default function EditHistory({
|
||||
receipts,
|
||||
setReceipts
|
||||
}: {
|
||||
receipts: ReceiptData[]
|
||||
setReceipts: (receipts: ReceiptData[]) => void
|
||||
}): ReactElement {
|
||||
const { asset } = useAsset()
|
||||
|
||||
function getUpdateType(type: string): string {
|
||||
@ -66,13 +73,11 @@ export default function EditHistory(): ReactElement {
|
||||
//
|
||||
// 2. Construct display data based on fetched data.
|
||||
//
|
||||
const [receipts, setReceipts] = useState<ReceiptData[]>()
|
||||
|
||||
useEffect(() => {
|
||||
if (!data || data.nftUpdates.length === 0) return
|
||||
const receiptCollection = data.nftUpdates
|
||||
setReceipts(receiptCollection)
|
||||
}, [data])
|
||||
}, [data, setReceipts])
|
||||
|
||||
return (
|
||||
<>
|
||||
|
@ -1,51 +0,0 @@
|
||||
.meta {
|
||||
margin-bottom: calc(var(--spacer) / 1.5);
|
||||
color: var(--color-secondary);
|
||||
font-size: var(--font-size-small);
|
||||
}
|
||||
|
||||
.asset {
|
||||
margin-left: -2rem;
|
||||
margin-right: -2rem;
|
||||
padding-left: 2rem;
|
||||
padding-right: 3rem;
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
margin-bottom: calc(var(--spacer) / 1.5);
|
||||
padding-bottom: calc(var(--spacer) / 1.75);
|
||||
}
|
||||
|
||||
@media (min-width: 40rem) {
|
||||
.asset {
|
||||
margin-top: -0.65rem;
|
||||
}
|
||||
}
|
||||
|
||||
.assetType {
|
||||
display: inline-block;
|
||||
border-right: 1px solid var(--border-color);
|
||||
padding-right: calc(var(--spacer) / 3.5);
|
||||
margin-right: calc(var(--spacer) / 4);
|
||||
}
|
||||
|
||||
.datatoken {
|
||||
white-space: pre;
|
||||
margin-right: calc(var(--spacer) / 3);
|
||||
}
|
||||
|
||||
.byline {
|
||||
font-size: var(--font-size-small);
|
||||
}
|
||||
|
||||
.updated {
|
||||
font-size: var(--font-size-mini);
|
||||
}
|
||||
|
||||
.addWrap {
|
||||
padding-left: calc(var(--spacer) / 5);
|
||||
border-left: 1px solid var(--border-color);
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.add {
|
||||
font-size: var(--font-size-mini);
|
||||
}
|
@ -1,75 +0,0 @@
|
||||
import React, { ReactElement } from 'react'
|
||||
import { useAsset } from '@context/Asset'
|
||||
import { useWeb3 } from '@context/Web3'
|
||||
import ExplorerLink from '@shared/ExplorerLink'
|
||||
import Publisher from '@shared/Publisher'
|
||||
import AddToken from '@shared/AddToken'
|
||||
import Time from '@shared/atoms/Time'
|
||||
import AssetType from '@shared/AssetType'
|
||||
import styles from './MetaMain.module.css'
|
||||
import { getServiceByName } from '@utils/ddo'
|
||||
import { Asset } from '@oceanprotocol/lib'
|
||||
|
||||
export default function MetaMain({ ddo }: { ddo: Asset }): ReactElement {
|
||||
const { isAssetNetwork } = useAsset()
|
||||
const { web3ProviderInfo } = useWeb3()
|
||||
|
||||
const isCompute = Boolean(getServiceByName(ddo, 'compute'))
|
||||
const accessType = isCompute ? 'compute' : 'access'
|
||||
const blockscoutNetworks = [1287, 2021000, 2021001, 44787, 246, 1285]
|
||||
const isBlockscoutExplorer = blockscoutNetworks.includes(ddo?.chainId)
|
||||
|
||||
const dataTokenName = ddo?.datatokens[0]?.name
|
||||
const dataTokenSymbol = ddo?.datatokens[0]?.symbol
|
||||
|
||||
return (
|
||||
<aside className={styles.meta}>
|
||||
<header className={styles.asset}>
|
||||
<AssetType
|
||||
type={ddo?.metadata.type}
|
||||
accessType={accessType}
|
||||
className={styles.assetType}
|
||||
/>
|
||||
<ExplorerLink
|
||||
className={styles.datatoken}
|
||||
networkId={ddo?.chainId}
|
||||
path={
|
||||
isBlockscoutExplorer
|
||||
? `tokens/${ddo?.services[0].datatokenAddress}`
|
||||
: `token/${ddo?.services[0].datatokenAddress}`
|
||||
}
|
||||
>
|
||||
{`${dataTokenName} — ${dataTokenSymbol}`}
|
||||
</ExplorerLink>
|
||||
|
||||
{web3ProviderInfo?.name === 'MetaMask' && isAssetNetwork && (
|
||||
<span className={styles.addWrap}>
|
||||
<AddToken
|
||||
address={ddo?.services[0].datatokenAddress}
|
||||
symbol={(ddo as Asset)?.datatokens[0]?.symbol}
|
||||
logo="https://raw.githubusercontent.com/oceanprotocol/art/main/logo/datatoken.png"
|
||||
text={`Add ${(ddo as Asset)?.datatokens[0]?.symbol} to wallet`}
|
||||
className={styles.add}
|
||||
minimal
|
||||
/>
|
||||
</span>
|
||||
)}
|
||||
</header>
|
||||
|
||||
<div className={styles.byline}>
|
||||
Published By <Publisher account={(ddo as Asset)?.nft?.owner} />
|
||||
<p>
|
||||
<Time date={ddo?.metadata.created} relative />
|
||||
{ddo?.metadata.created !== ddo?.metadata.updated && (
|
||||
<>
|
||||
{' — '}
|
||||
<span className={styles.updated}>
|
||||
updated <Time date={ddo?.metadata.updated} relative />
|
||||
</span>
|
||||
</>
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
</aside>
|
||||
)
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
.wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
padding-left: calc(var(--spacer) / 2);
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.datatoken {
|
||||
white-space: pre;
|
||||
margin-right: calc(var(--spacer) / 3);
|
||||
}
|
||||
|
||||
.owner {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.addWrap {
|
||||
padding-left: calc(var(--spacer) / 5);
|
||||
border-left: 1px solid var(--border-color);
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.add {
|
||||
font-size: var(--font-size-mini);
|
||||
}
|
54
src/components/Asset/AssetContent/MetaMain/MetaAsset.tsx
Normal file
54
src/components/Asset/AssetContent/MetaMain/MetaAsset.tsx
Normal file
@ -0,0 +1,54 @@
|
||||
import { useAsset } from '@context/Asset'
|
||||
import { useWeb3 } from '@context/Web3'
|
||||
import { Asset } from '@oceanprotocol/lib'
|
||||
import AddToken from '@shared/AddToken'
|
||||
import ExplorerLink from '@shared/ExplorerLink'
|
||||
import Publisher from '@shared/Publisher'
|
||||
import React, { ReactElement } from 'react'
|
||||
import styles from './MetaAsset.module.css'
|
||||
|
||||
export default function MetaAsset({
|
||||
asset,
|
||||
isBlockscoutExplorer
|
||||
}: {
|
||||
asset: Asset
|
||||
isBlockscoutExplorer: boolean
|
||||
}): ReactElement {
|
||||
const { isAssetNetwork } = useAsset()
|
||||
const { web3ProviderInfo } = useWeb3()
|
||||
|
||||
const dataTokenSymbol = asset?.datatokens[0]?.symbol
|
||||
|
||||
return (
|
||||
<div className={styles.wrapper}>
|
||||
<span className={styles.owner}>
|
||||
Owned by <Publisher account={asset?.nft?.owner} />
|
||||
</span>
|
||||
<span>
|
||||
<ExplorerLink
|
||||
className={styles.datatoken}
|
||||
networkId={asset?.chainId}
|
||||
path={
|
||||
isBlockscoutExplorer
|
||||
? `tokens/${asset?.services[0].datatokenAddress}`
|
||||
: `token/${asset?.services[0].datatokenAddress}`
|
||||
}
|
||||
>
|
||||
{`Accessed with ${dataTokenSymbol}`}
|
||||
</ExplorerLink>
|
||||
{web3ProviderInfo?.name === 'MetaMask' && isAssetNetwork && (
|
||||
<span className={styles.addWrap}>
|
||||
<AddToken
|
||||
address={asset?.services[0].datatokenAddress}
|
||||
symbol={(asset as Asset)?.datatokens[0]?.symbol}
|
||||
logo="https://raw.githubusercontent.com/oceanprotocol/art/main/logo/datatoken.png"
|
||||
text={`Add ${(asset as Asset)?.datatokens[0]?.symbol} to wallet`}
|
||||
className={styles.add}
|
||||
minimal
|
||||
/>
|
||||
</span>
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
.wrapper {
|
||||
padding: calc(var(--spacer) / 2);
|
||||
}
|
||||
|
||||
.assetType {
|
||||
display: inline-block;
|
||||
border-right: 1px solid var(--border-color);
|
||||
padding-right: calc(var(--spacer) / 3.5);
|
||||
margin-right: calc(var(--spacer) / 4);
|
||||
}
|
||||
|
||||
.byline {
|
||||
display: inline-block;
|
||||
font-size: var(--font-size-small);
|
||||
}
|
||||
|
||||
.updated {
|
||||
font-size: var(--font-size-mini);
|
||||
}
|
47
src/components/Asset/AssetContent/MetaMain/MetaInfo.tsx
Normal file
47
src/components/Asset/AssetContent/MetaMain/MetaInfo.tsx
Normal file
@ -0,0 +1,47 @@
|
||||
import { Asset } from '@oceanprotocol/lib'
|
||||
import AssetType from '@shared/AssetType'
|
||||
import Time from '@shared/atoms/Time'
|
||||
import Publisher from '@shared/Publisher'
|
||||
import { getServiceByName } from '@utils/ddo'
|
||||
import React, { ReactElement } from 'react'
|
||||
import styles from './MetaInfo.module.css'
|
||||
|
||||
export default function MetaInfo({
|
||||
asset,
|
||||
nftPublisher
|
||||
}: {
|
||||
asset: Asset
|
||||
nftPublisher: string
|
||||
}): ReactElement {
|
||||
const isCompute = Boolean(getServiceByName(asset, 'compute'))
|
||||
const accessType = isCompute ? 'compute' : 'access'
|
||||
const nftOwner = asset?.nft?.owner
|
||||
|
||||
return (
|
||||
<div className={styles.wrapper}>
|
||||
<AssetType
|
||||
type={asset?.metadata.type}
|
||||
accessType={accessType}
|
||||
className={styles.assetType}
|
||||
/>
|
||||
<div className={styles.byline}>
|
||||
<p>
|
||||
Published <Time date={asset?.metadata.created} relative />
|
||||
{nftPublisher && nftPublisher !== nftOwner && (
|
||||
<span>
|
||||
{' by '} <Publisher account={nftPublisher} />
|
||||
</span>
|
||||
)}
|
||||
{asset?.metadata.created !== asset?.metadata.updated && (
|
||||
<>
|
||||
{' — '}
|
||||
<span className={styles.updated}>
|
||||
updated <Time date={asset?.metadata.updated} relative />
|
||||
</span>
|
||||
</>
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
.wrapper {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.wrapper img {
|
||||
margin: 0;
|
||||
width: 128px;
|
||||
height: 128px;
|
||||
}
|
||||
|
||||
.info {
|
||||
padding: calc(var(--spacer) / 2);
|
||||
color: var(--color-secondary);
|
||||
}
|
||||
|
||||
.info h5 {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.address {
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.address button::after {
|
||||
word-break: normal;
|
||||
}
|
||||
|
||||
.links {
|
||||
margin-top: calc(var(--spacer) / 3);
|
||||
}
|
||||
|
||||
.links a {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.fallback {
|
||||
padding-top: calc(var(--spacer) / 3);
|
||||
font-style: italic;
|
||||
}
|
79
src/components/Asset/AssetContent/MetaMain/NftTooltip.tsx
Normal file
79
src/components/Asset/AssetContent/MetaMain/NftTooltip.tsx
Normal file
@ -0,0 +1,79 @@
|
||||
import Copy from '@shared/atoms/Copy'
|
||||
import External from '@images/external.svg'
|
||||
import ExplorerLink from '@shared/ExplorerLink'
|
||||
import { NftMetadata } from '@utils/nft'
|
||||
import React, { ReactElement } from 'react'
|
||||
import styles from './NftTooltip.module.css'
|
||||
import explorerLinkStyles from '@shared/ExplorerLink/index.module.css'
|
||||
import { accountTruncate } from '@utils/web3'
|
||||
|
||||
export default function NftTooltip({
|
||||
nft,
|
||||
address,
|
||||
chainId,
|
||||
isBlockscoutExplorer
|
||||
}: {
|
||||
nft: NftMetadata
|
||||
address: string
|
||||
chainId: number
|
||||
isBlockscoutExplorer: boolean
|
||||
}): ReactElement {
|
||||
// Currently Ocean NFTs are not displayed correctly on OpenSea
|
||||
// Code prepared to easily integrate this feature once this is fixed
|
||||
//
|
||||
// Supported OpeanSea networks:
|
||||
// https://support.opensea.io/hc/en-us/articles/4404027708051-Which-blockchains-does-OpenSea-support-
|
||||
const openseaNetworks = [1, 137]
|
||||
const openseaTestNetworks = [4]
|
||||
const openSeaSupported = openseaNetworks
|
||||
.concat(openseaTestNetworks)
|
||||
.includes(chainId)
|
||||
|
||||
const openSeaBaseUri = openSeaSupported
|
||||
? openseaTestNetworks.includes(chainId)
|
||||
? 'https://testnets.opensea.io'
|
||||
: 'https://opensea.io'
|
||||
: undefined
|
||||
|
||||
return (
|
||||
<div className={styles.wrapper}>
|
||||
{nft && <img src={nft.image_data} alt={nft?.name} />}
|
||||
<div className={styles.info}>
|
||||
{nft && <h5>{nft.name}</h5>}
|
||||
{address && (
|
||||
<span title={address} className={styles.address}>
|
||||
{accountTruncate(address)} <Copy text={address} />
|
||||
</span>
|
||||
)}
|
||||
<div className={styles.links}>
|
||||
{address && (
|
||||
<ExplorerLink
|
||||
networkId={chainId}
|
||||
path={
|
||||
isBlockscoutExplorer ? `tokens/${address}` : `token/${address}`
|
||||
}
|
||||
>
|
||||
View on explorer
|
||||
</ExplorerLink>
|
||||
)}
|
||||
|
||||
{openSeaSupported && nft && address && (
|
||||
<a
|
||||
href={`${openSeaBaseUri}/assets/${address}/1`}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className={explorerLinkStyles.link}
|
||||
>
|
||||
View on OpeanSea <External />
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
{!nft?.image_data && (
|
||||
<p className={styles.fallback}>
|
||||
This Data NFT was not created on Ocean Market
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
44
src/components/Asset/AssetContent/MetaMain/index.module.css
Normal file
44
src/components/Asset/AssetContent/MetaMain/index.module.css
Normal file
@ -0,0 +1,44 @@
|
||||
.meta {
|
||||
margin-left: calc(var(--spacer) * -1);
|
||||
margin-right: calc(var(--spacer) * -1);
|
||||
margin-bottom: calc(var(--spacer) / 1.5);
|
||||
color: var(--color-secondary);
|
||||
font-size: var(--font-size-small);
|
||||
}
|
||||
|
||||
.asset {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
height: calc(var(--spacer) * 2);
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
.nftImage {
|
||||
position: relative;
|
||||
margin: 0;
|
||||
border-right: 1px solid var(--border-color);
|
||||
width: calc(var(--spacer) * 2);
|
||||
height: calc(var(--spacer) * 2);
|
||||
}
|
||||
|
||||
.nftImage img,
|
||||
.nftImage > svg:first-of-type {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.nftImage > svg:first-of-type {
|
||||
transform: scale(0.7);
|
||||
}
|
||||
|
||||
.nftImage .tooltip {
|
||||
position: absolute;
|
||||
padding: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.nftImage .tooltip svg {
|
||||
fill: var(--font-color-text);
|
||||
}
|
53
src/components/Asset/AssetContent/MetaMain/index.tsx
Normal file
53
src/components/Asset/AssetContent/MetaMain/index.tsx
Normal file
@ -0,0 +1,53 @@
|
||||
import React, { ReactElement } from 'react'
|
||||
import styles from './index.module.css'
|
||||
import { Asset } from '@oceanprotocol/lib'
|
||||
import { decodeTokenURI } from '@utils/nft'
|
||||
import MetaAsset from './MetaAsset'
|
||||
import MetaInfo from './MetaInfo'
|
||||
import Tooltip from '@shared/atoms/Tooltip'
|
||||
import NftTooltip from './NftTooltip'
|
||||
import Logo from '@shared/atoms/Logo'
|
||||
|
||||
export default function MetaMain({
|
||||
asset,
|
||||
nftPublisher
|
||||
}: {
|
||||
asset: Asset
|
||||
nftPublisher: string
|
||||
}): ReactElement {
|
||||
const nftMetadata = decodeTokenURI(asset?.nft?.tokenURI)
|
||||
|
||||
const blockscoutNetworks = [1287, 2021000, 2021001, 44787, 246, 1285]
|
||||
const isBlockscoutExplorer = blockscoutNetworks.includes(asset?.chainId)
|
||||
|
||||
return (
|
||||
<aside className={styles.meta}>
|
||||
<header className={styles.asset}>
|
||||
<div className={styles.nftImage}>
|
||||
{nftMetadata?.image_data ? (
|
||||
<img src={nftMetadata?.image_data} alt={asset?.nft?.name} />
|
||||
) : (
|
||||
<Logo noWordmark />
|
||||
)}
|
||||
|
||||
{(nftMetadata || asset?.nftAddress) && (
|
||||
<Tooltip
|
||||
className={styles.tooltip}
|
||||
content={
|
||||
<NftTooltip
|
||||
nft={nftMetadata}
|
||||
address={asset?.nftAddress}
|
||||
chainId={asset?.chainId}
|
||||
isBlockscoutExplorer={isBlockscoutExplorer}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<MetaAsset asset={asset} isBlockscoutExplorer={isBlockscoutExplorer} />
|
||||
</header>
|
||||
|
||||
<MetaInfo asset={asset} nftPublisher={nftPublisher} />
|
||||
</aside>
|
||||
)
|
||||
}
|
@ -16,6 +16,7 @@
|
||||
|
||||
.content {
|
||||
composes: box from '@shared/atoms/Box.module.css';
|
||||
padding-top: 0;
|
||||
margin-top: var(--spacer);
|
||||
position: relative;
|
||||
}
|
||||
|
@ -16,16 +16,27 @@ import NetworkName from '@shared/NetworkName'
|
||||
import content from '../../../../content/purgatory.json'
|
||||
import { AssetExtended } from 'src/@types/AssetExtended'
|
||||
import { useWeb3 } from '@context/Web3'
|
||||
import Web3 from 'web3'
|
||||
|
||||
export default function AssetContent({
|
||||
asset
|
||||
}: {
|
||||
asset: AssetExtended
|
||||
}): ReactElement {
|
||||
const { debug } = useUserPreferences()
|
||||
const [isOwner, setIsOwner] = useState(false)
|
||||
const { accountId } = useWeb3()
|
||||
const { isInPurgatory, purgatoryData, owner, isAssetNetwork } = useAsset()
|
||||
const { debug } = useUserPreferences()
|
||||
const [receipts, setReceipts] = useState([])
|
||||
const [nftPublisher, setNftPublisher] = useState<string>()
|
||||
|
||||
useEffect(() => {
|
||||
setNftPublisher(
|
||||
Web3.utils.toChecksumAddress(
|
||||
receipts?.find((e) => e.type === 'METADATA_CREATED')?.nft?.owner
|
||||
)
|
||||
)
|
||||
}, [receipts])
|
||||
|
||||
useEffect(() => {
|
||||
if (!accountId || !owner) return
|
||||
@ -43,11 +54,10 @@ export default function AssetContent({
|
||||
<article className={styles.grid}>
|
||||
<div>
|
||||
<div className={styles.content}>
|
||||
<MetaMain ddo={asset} />
|
||||
<MetaMain asset={asset} nftPublisher={nftPublisher} />
|
||||
{asset?.accessDetails?.datatoken !== null && (
|
||||
<Bookmark did={asset?.id} />
|
||||
)}
|
||||
|
||||
{isInPurgatory === true ? (
|
||||
<Alert
|
||||
title={content.asset.title}
|
||||
@ -64,9 +74,8 @@ export default function AssetContent({
|
||||
<MetaSecondary ddo={asset} />
|
||||
</>
|
||||
)}
|
||||
|
||||
<MetaFull ddo={asset} />
|
||||
<EditHistory />
|
||||
<EditHistory receipts={receipts} setReceipts={setReceipts} />
|
||||
{debug === true && <DebugOutput title="DDO" output={asset} />}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -181,6 +181,7 @@ export async function transformPublishFormToDdo(
|
||||
}
|
||||
],
|
||||
nft: {
|
||||
...generateNftCreateData(values?.metadata.nft),
|
||||
owner: accountId
|
||||
}
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user