Commit 92a6ec67 authored by Jack Short's avatar Jack Short Committed by GitHub

feat: [DetailsV2] different media types on landing page (#6492)

* initial layout assuming media type exists

* fixing embeds

* media type function

* updated snapshot test

* initial shadow impl

* better shadows

* audio player controls

* updating tests

* content not available handlers

* errors on all media types

* removing fullscreen from iframe

* adding snapshot tests

* responding to comments

* text align center

* updating tests
parent 1d6a1e90
...@@ -3,7 +3,9 @@ import Row from 'components/Row' ...@@ -3,7 +3,9 @@ import Row from 'components/Row'
import { VerifiedIcon } from 'nft/components/icons' import { VerifiedIcon } from 'nft/components/icons'
import { CollectionInfoForAsset, GenieAsset } from 'nft/types' import { CollectionInfoForAsset, GenieAsset } from 'nft/types'
import styled from 'styled-components/macro' import styled from 'styled-components/macro'
import { BREAKPOINTS, ThemedText } from 'theme' import { BREAKPOINTS } from 'theme'
import { MediaRenderer } from './MediaRenderer'
const MAX_WIDTH = 560 const MAX_WIDTH = 560
...@@ -14,6 +16,7 @@ const LandingPageContainer = styled.div` ...@@ -14,6 +16,7 @@ const LandingPageContainer = styled.div`
align-items: center; align-items: center;
padding: 22px 20px 0px; padding: 22px 20px 0px;
gap: 26px; gap: 26px;
width: 100%;
@media screen and (min-width: ${BREAKPOINTS.sm}px) { @media screen and (min-width: ${BREAKPOINTS.sm}px) {
gap: 64px; gap: 64px;
...@@ -29,6 +32,7 @@ const LandingPageContainer = styled.div` ...@@ -29,6 +32,7 @@ const LandingPageContainer = styled.div`
padding-top: 0px; padding-top: 0px;
padding-bottom: ${({ theme }) => `${theme.navHeight}px`}; padding-bottom: ${({ theme }) => `${theme.navHeight}px`};
gap: 80px; gap: 80px;
justify-content: center;
} }
` `
...@@ -40,40 +44,57 @@ const InfoContainer = styled(ColumnCenter)` ...@@ -40,40 +44,57 @@ const InfoContainer = styled(ColumnCenter)`
} }
` `
const InfoDetailsContainer = styled(Column)` const StyledHeadlineText = styled.div`
gap: 4px; font-weight: 600;
align-items: center; font-size: 20px;
` line-height: 28px;
text-align: center;
const MediaContainer = styled.div` color: ${({ theme }) => theme.textPrimary};
width: 100%;
height: 100%;
@media screen and (min-width: ${BREAKPOINTS.sm}px) { @media screen and (min-width: ${BREAKPOINTS.sm}px) {
width: ${MAX_WIDTH}px; line-height: 44px;
height: ${MAX_WIDTH}px; font-size: 36px;
} }
` `
const StyledSubheaderText = styled.div`
font-weight: 500;
font-size: 14px;
line-height: 20px;
text-align: center;
color: ${({ theme }) => theme.textSecondary};
const StyledMedia = styled.img` @media screen and (min-width: ${BREAKPOINTS.sm}px) {
object-fit: contain; line-height: 24px;
height: 100%; font-size: 16px;
width: 100%; }
` `
const StyledSubheaderText = styled(ThemedText.SubHeaderSmall)` const InfoDetailsContainer = styled(Column)`
line-height: 20px; gap: 4px;
align-items: center;
@media screen and (min-width: ${BREAKPOINTS.sm}px) { @media screen and (min-width: ${BREAKPOINTS.sm}px) {
line-height: 24px !important; ${StyledHeadlineText} {
font-size: 16px !important; line-height: 44px;
font-size: 36px;
}
${StyledSubheaderText} {
line-height: 24px;
font-size: 16px;
}
} }
` `
const StyledHeadlineText = styled(ThemedText.HeadlineSmall)` const MediaContainer = styled.div`
position: relative;
width: 100%;
height: 100%;
filter: drop-shadow(0px 12px 20px rgba(0, 0, 0, 0.1));
@media screen and (min-width: ${BREAKPOINTS.sm}px) { @media screen and (min-width: ${BREAKPOINTS.sm}px) {
line-height: 44px !important; width: ${MAX_WIDTH}px;
font-size: 36px !important; height: ${MAX_WIDTH}px;
} }
` `
...@@ -86,7 +107,7 @@ export const LandingPage = ({ asset, collection }: LandingPageProps) => { ...@@ -86,7 +107,7 @@ export const LandingPage = ({ asset, collection }: LandingPageProps) => {
return ( return (
<LandingPageContainer> <LandingPageContainer>
<MediaContainer> <MediaContainer>
<StyledMedia src={asset.imageUrl} /> <MediaRenderer asset={asset} />
</MediaContainer> </MediaContainer>
<InfoContainer> <InfoContainer>
<InfoDetailsContainer> <InfoDetailsContainer>
......
import {
TEST_AUDIO_NFT_ASSET,
TEST_EMBEDDED_NFT_ASSET,
TEST_NFT_ASSET,
TEST_VIDEO_NFT_ASSET,
} from 'test-utils/nft/fixtures'
import { render } from 'test-utils/render'
import { MediaRenderer } from './MediaRenderer'
describe('Media renderer', () => {
it('renders image nft correctly', () => {
const { asFragment } = render(<MediaRenderer asset={TEST_NFT_ASSET} />)
expect(asFragment()).toMatchSnapshot()
})
it('renders an embedded nft correctly', () => {
const { asFragment } = render(<MediaRenderer asset={TEST_EMBEDDED_NFT_ASSET} />)
expect(asFragment()).toMatchSnapshot()
})
it('renders a video nft correctly', () => {
const { asFragment } = render(<MediaRenderer asset={TEST_VIDEO_NFT_ASSET} />)
expect(asFragment()).toMatchSnapshot()
})
it('renders an audio nft correctly', () => {
const { asFragment } = render(<MediaRenderer asset={TEST_AUDIO_NFT_ASSET} />)
expect(asFragment()).toMatchSnapshot()
})
})
import { GenieAsset } from 'nft/types'
import { isAudio, isVideo } from 'nft/utils'
import { useState } from 'react'
import styled, { css } from 'styled-components/macro'
import { BREAKPOINTS, ThemedText } from 'theme'
const MediaStyle = css`
position: relative;
object-fit: contain;
height: 100%;
width: 100%;
aspect-ratio: 1;
z-index: 1;
`
const StyledImage = styled.img`
${MediaStyle}
`
const StyledVideo = styled.video`
${MediaStyle}
`
const MediaShadow = styled.img`
object-fit: contain;
height: 100%;
aspect-ratio: 1;
border-radius: 20px;
filter: blur(25px);
@media screen and (min-width: ${BREAKPOINTS.xl}px) {
filter: blur(50px);
}
`
const MediaShadowContainer = styled.div`
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
`
const StyledEmbed = styled.div`
position: relative;
overflow: hidden;
width: 100%;
padding-top: 100%;
z-index: 1;
`
const StyledIFrame = styled.iframe`
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
`
const AudioContainer = styled.div`
position: relative;
`
const StyledAudio = styled.audio`
position: absolute;
left: 0;
bottom: 0;
z-index: 2;
width: 100%;
`
const AudioPlayer = ({ asset, onError }: { asset: GenieAsset; onError: () => void }) => {
return (
<AudioContainer>
<StyledImage
src={asset.imageUrl}
alt={asset.name ?? asset.collectionName + ' #' + asset.tokenId}
onError={onError}
/>
<StyledAudio controls src={asset.animationUrl} onError={onError} />
</AudioContainer>
)
}
const EmbeddedMediaPlayer = ({ asset, onError }: { asset: GenieAsset; onError: () => void }) => {
return (
<StyledEmbed>
<StyledIFrame
title={asset.name ?? `${asset.collectionName} #${asset.tokenId}`}
src={asset.animationUrl}
frameBorder={0}
sandbox="allow-scripts"
allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
onError={onError}
/>
</StyledEmbed>
)
}
const ContentNotAvailable = styled(ThemedText.BodySmall)`
display: flex;
background-color: ${({ theme }) => theme.backgroundSurface};
color: ${({ theme }) => theme.textSecondary};
align-items: center;
justify-content: center;
${MediaStyle}
`
// TODO: when assets query is moved to nxyz update with mediaType from the query
enum MediaType {
Audio = 'audio',
Video = 'video',
Image = 'image',
Raw = 'raw',
}
function assetMediaType(asset: GenieAsset): MediaType {
if (isAudio(asset.animationUrl ?? '')) {
return MediaType.Audio
} else if (isVideo(asset.animationUrl ?? '')) {
return MediaType.Video
} else if (asset.animationUrl) {
return MediaType.Raw
}
return MediaType.Image
}
const RenderMediaShadow = ({ imageUrl }: { imageUrl: string | undefined }) => {
const [contentNotAvailable, setContentNotAvailable] = useState(false)
if (!imageUrl || contentNotAvailable) {
return null
}
return (
<MediaShadowContainer>
<MediaShadow src={imageUrl} onError={() => setContentNotAvailable(true)} />
</MediaShadowContainer>
)
}
const RenderMediaType = ({ asset }: { asset: GenieAsset }) => {
const [contentNotAvailable, setContentNotAvailable] = useState(false)
if (contentNotAvailable) {
return <ContentNotAvailable>Content not available</ContentNotAvailable>
}
switch (assetMediaType(asset)) {
case MediaType.Image:
return (
<StyledImage
src={asset.imageUrl}
alt={asset.name || asset.collectionName}
onError={() => setContentNotAvailable(true)}
/>
)
case MediaType.Video:
return (
<StyledVideo
src={asset.animationUrl}
autoPlay
controls
muted
loop
onError={() => setContentNotAvailable(true)}
/>
)
case MediaType.Audio:
return <AudioPlayer asset={asset} onError={() => setContentNotAvailable(true)} />
case MediaType.Raw:
return <EmbeddedMediaPlayer asset={asset} onError={() => setContentNotAvailable(true)} />
}
}
export const MediaRenderer = ({ asset }: { asset: GenieAsset }) => (
<>
<RenderMediaType asset={asset} />
<RenderMediaShadow imageUrl={asset.imageUrl} />
</>
)
...@@ -2,13 +2,13 @@ ...@@ -2,13 +2,13 @@
exports[`LandingPage renders it correctly 1`] = ` exports[`LandingPage renders it correctly 1`] = `
<DocumentFragment> <DocumentFragment>
.c7 { .c9 {
box-sizing: border-box; box-sizing: border-box;
margin: 0; margin: 0;
min-width: 0; min-width: 0;
} }
.c8 { .c10 {
width: 100%; width: 100%;
display: -webkit-box; display: -webkit-box;
display: -webkit-flex; display: -webkit-flex;
...@@ -26,15 +26,7 @@ exports[`LandingPage renders it correctly 1`] = ` ...@@ -26,15 +26,7 @@ exports[`LandingPage renders it correctly 1`] = `
gap: 4px; gap: 4px;
} }
.c9 { .c5 {
color: #7780A0;
}
.c11 {
color: #0D111C;
}
.c3 {
display: -webkit-box; display: -webkit-box;
display: -webkit-flex; display: -webkit-flex;
display: -ms-flexbox; display: -ms-flexbox;
...@@ -48,7 +40,7 @@ exports[`LandingPage renders it correctly 1`] = ` ...@@ -48,7 +40,7 @@ exports[`LandingPage renders it correctly 1`] = `
justify-content: flex-start; justify-content: flex-start;
} }
.c4 { .c6 {
width: 100%; width: 100%;
-webkit-align-items: center; -webkit-align-items: center;
-webkit-box-align: center; -webkit-box-align: center;
...@@ -56,6 +48,32 @@ exports[`LandingPage renders it correctly 1`] = ` ...@@ -56,6 +48,32 @@ exports[`LandingPage renders it correctly 1`] = `
align-items: center; align-items: center;
} }
.c2 {
position: relative;
object-fit: contain;
height: 100%;
width: 100%;
aspect-ratio: 1;
z-index: 1;
}
.c4 {
object-fit: contain;
height: 100%;
aspect-ratio: 1;
border-radius: 20px;
-webkit-filter: blur(25px);
filter: blur(25px);
}
.c3 {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
}
.c0 { .c0 {
display: -webkit-box; display: -webkit-box;
display: -webkit-flex; display: -webkit-flex;
...@@ -71,13 +89,30 @@ exports[`LandingPage renders it correctly 1`] = ` ...@@ -71,13 +89,30 @@ exports[`LandingPage renders it correctly 1`] = `
align-items: center; align-items: center;
padding: 22px 20px 0px; padding: 22px 20px 0px;
gap: 26px; gap: 26px;
width: 100%;
} }
.c5 { .c7 {
gap: 40px; gap: 40px;
} }
.c6 { .c14 {
font-weight: 600;
font-size: 20px;
line-height: 28px;
text-align: center;
color: #0D111C;
}
.c12 {
font-weight: 500;
font-size: 14px;
line-height: 20px;
text-align: center;
color: #7780A0;
}
.c8 {
gap: 4px; gap: 4px;
-webkit-align-items: center; -webkit-align-items: center;
-webkit-box-align: center; -webkit-box-align: center;
...@@ -86,18 +121,18 @@ exports[`LandingPage renders it correctly 1`] = ` ...@@ -86,18 +121,18 @@ exports[`LandingPage renders it correctly 1`] = `
} }
.c1 { .c1 {
position: relative;
width: 100%; width: 100%;
height: 100%; height: 100%;
-webkit-filter: drop-shadow(0px 12px 20px rgba(0,0,0,0.1));
filter: drop-shadow(0px 12px 20px rgba(0,0,0,0.1));
} }
.c2 { @media screen and (min-width:1280px) {
object-fit: contain; .c4 {
height: 100%; -webkit-filter: blur(50px);
width: 100%; filter: blur(50px);
} }
.c10 {
line-height: 20px;
} }
@media screen and (min-width:640px) { @media screen and (min-width:640px) {
...@@ -121,33 +156,49 @@ exports[`LandingPage renders it correctly 1`] = ` ...@@ -121,33 +156,49 @@ exports[`LandingPage renders it correctly 1`] = `
padding-top: 0px; padding-top: 0px;
padding-bottom: 72px; padding-bottom: 72px;
gap: 80px; gap: 80px;
-webkit-box-pack: center;
-webkit-justify-content: center;
-ms-flex-pack: center;
justify-content: center;
} }
} }
@media screen and (min-width:640px) { @media screen and (min-width:640px) {
.c5 { .c7 {
width: 560px; width: 560px;
} }
} }
@media screen and (min-width:640px) { @media screen and (min-width:640px) {
.c1 { .c14 {
width: 560px; line-height: 44px;
height: 560px; font-size: 36px;
} }
} }
@media screen and (min-width:640px) { @media screen and (min-width:640px) {
.c10 { .c12 {
line-height: 24px !important; line-height: 24px;
font-size: 16px !important; font-size: 16px;
} }
} }
@media screen and (min-width:640px) { @media screen and (min-width:640px) {
.c12 { .c8 .c13 {
line-height: 44px !important; line-height: 44px;
font-size: 36px !important; font-size: 36px;
}
.c8 .c11 {
line-height: 24px;
font-size: 16px;
}
}
@media screen and (min-width:640px) {
.c1 {
width: 560px;
height: 560px;
} }
} }
...@@ -158,21 +209,30 @@ exports[`LandingPage renders it correctly 1`] = ` ...@@ -158,21 +209,30 @@ exports[`LandingPage renders it correctly 1`] = `
class="c1" class="c1"
> >
<img <img
alt="Azuki #3318"
class="c2" class="c2"
src="https://cdn.center.app/1/0xED5AF388653567Af2F388E6224dC7C4b3241C544/3318/50ed67ad647d0aa0cad0b830d136a677efc2fb72a44587bc35f2a5fb334a7fdf.png" src="https://cdn.center.app/1/0xED5AF388653567Af2F388E6224dC7C4b3241C544/3318/50ed67ad647d0aa0cad0b830d136a677efc2fb72a44587bc35f2a5fb334a7fdf.png"
/> />
<div
class="c3"
>
<img
class="c4"
src="https://cdn.center.app/1/0xED5AF388653567Af2F388E6224dC7C4b3241C544/3318/50ed67ad647d0aa0cad0b830d136a677efc2fb72a44587bc35f2a5fb334a7fdf.png"
/>
</div>
</div> </div>
<div <div
class="c3 c4 c5" class="c5 c6 c7"
> >
<div <div
class="c3 c6" class="c5 c8"
> >
<div <div
class="c7 c8" class="c9 c10"
> >
<div <div
class="c9 c10 css-1aekuku" class="c11 c12"
> >
Azuki Azuki
</div> </div>
...@@ -194,7 +254,7 @@ exports[`LandingPage renders it correctly 1`] = ` ...@@ -194,7 +254,7 @@ exports[`LandingPage renders it correctly 1`] = `
</svg> </svg>
</div> </div>
<div <div
class="c11 c12 css-iapcxi" class="c13 c14"
> >
Azuki #3318 Azuki #3318
</div> </div>
......
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Media renderer renders a video nft correctly 1`] = `
<DocumentFragment>
.c0 {
position: relative;
object-fit: contain;
height: 100%;
width: 100%;
aspect-ratio: 1;
z-index: 1;
}
@media screen and (min-width:1280px) {
}
<video
autoplay=""
class="c0"
controls=""
loop=""
src="https://openseauserdata.com/files/5af92728200027caa4f3f5ae87a486a7.mp4"
/>
.c1 {
object-fit: contain;
height: 100%;
aspect-ratio: 1;
border-radius: 20px;
-webkit-filter: blur(25px);
filter: blur(25px);
}
.c0 {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
}
@media screen and (min-width:1280px) {
.c1 {
-webkit-filter: blur(50px);
filter: blur(50px);
}
}
<div
class="c0"
>
<img
class="c1"
src="https://i.seadn.io/gae/tkDbNhjjBZV2PmYaJbJOOigywZCrlcyGRxeQFkZS1YZyihyG5GoWNWj3N9f1T7YVuaxOqdxhfJylC9ejtoCvdgBE932vd7jorVqA?w=500&auto=format"
/>
</div>
</DocumentFragment>
`;
exports[`Media renderer renders an audio nft correctly 1`] = `
<DocumentFragment>
.c1 {
position: relative;
object-fit: contain;
height: 100%;
width: 100%;
aspect-ratio: 1;
z-index: 1;
}
.c0 {
position: relative;
}
.c2 {
position: absolute;
left: 0;
bottom: 0;
z-index: 2;
width: 100%;
}
@media screen and (min-width:1280px) {
}
<div
class="c0"
>
<img
alt="Death Row Session: Vol. 2 (420 Edition) #320"
class="c1"
src="https://i.seadn.io/gae/Kze9SBqn_6O0qrHKxspo1gRkkDV2A5EmTeWtvdS-dNxBsvi_wPXUYjc6De0sUC-DYzL093102mUftenWxwWuTelqsdw-ngoBC3o2XFU?w=500&auto=format"
/>
<audio
class="c2"
controls=""
src="https://openseauserdata.com/files/4a22253e44e10baa11484a2e43efefda.mp3"
/>
</div>
.c1 {
object-fit: contain;
height: 100%;
aspect-ratio: 1;
border-radius: 20px;
-webkit-filter: blur(25px);
filter: blur(25px);
}
.c0 {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
}
@media screen and (min-width:1280px) {
.c1 {
-webkit-filter: blur(50px);
filter: blur(50px);
}
}
<div
class="c0"
>
<img
class="c1"
src="https://i.seadn.io/gae/Kze9SBqn_6O0qrHKxspo1gRkkDV2A5EmTeWtvdS-dNxBsvi_wPXUYjc6De0sUC-DYzL093102mUftenWxwWuTelqsdw-ngoBC3o2XFU?w=500&auto=format"
/>
</div>
</DocumentFragment>
`;
exports[`Media renderer renders an embedded nft correctly 1`] = `
<DocumentFragment>
.c0 {
position: relative;
overflow: hidden;
width: 100%;
padding-top: 100%;
z-index: 1;
}
.c1 {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
}
@media screen and (min-width:1280px) {
}
<div
class="c0"
>
<iframe
allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
class="c1"
frameborder="0"
sandbox="allow-scripts"
src="https://tokens.mathcastles.xyz/terraforms/token-html/7202"
title="Level 13 at {28, 3}"
/>
</div>
.c1 {
object-fit: contain;
height: 100%;
aspect-ratio: 1;
border-radius: 20px;
-webkit-filter: blur(25px);
filter: blur(25px);
}
.c0 {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
}
@media screen and (min-width:1280px) {
.c1 {
-webkit-filter: blur(50px);
filter: blur(50px);
}
}
<div
class="c0"
>
<img
class="c1"
src="https://cdn.center.app/v2/1/06ff92279474add6ce06176e2a65447396edf786d169d8ccc03fddfa45ce004f/bb01f8a2f093ea4619498dae58fc19e5ba3fa38a84cabf92948994609489d566.png"
/>
</div>
</DocumentFragment>
`;
exports[`Media renderer renders image nft correctly 1`] = `
<DocumentFragment>
.c0 {
position: relative;
object-fit: contain;
height: 100%;
width: 100%;
aspect-ratio: 1;
z-index: 1;
}
@media screen and (min-width:1280px) {
}
<img
alt="Azuki #3318"
class="c0"
src="https://cdn.center.app/1/0xED5AF388653567Af2F388E6224dC7C4b3241C544/3318/50ed67ad647d0aa0cad0b830d136a677efc2fb72a44587bc35f2a5fb334a7fdf.png"
/>
.c1 {
object-fit: contain;
height: 100%;
aspect-ratio: 1;
border-radius: 20px;
-webkit-filter: blur(25px);
filter: blur(25px);
}
.c0 {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
}
@media screen and (min-width:1280px) {
.c1 {
-webkit-filter: blur(50px);
filter: blur(50px);
}
}
<div
class="c0"
>
<img
class="c1"
src="https://cdn.center.app/1/0xED5AF388653567Af2F388E6224dC7C4b3241C544/3318/50ed67ad647d0aa0cad0b830d136a677efc2fb72a44587bc35f2a5fb334a7fdf.png"
/>
</div>
</DocumentFragment>
`;
import { NftStandard } from 'graphql/data/__generated__/types-and-hooks' import { MediaType, NftStandard } from 'graphql/data/__generated__/types-and-hooks'
import { SortBy } from 'nft/hooks' import { SortBy } from 'nft/hooks'
import { SellOrder } from '../sell' import { SellOrder } from '../sell'
...@@ -87,6 +87,7 @@ export interface GenieAsset { ...@@ -87,6 +87,7 @@ export interface GenieAsset {
collectionSymbol?: string collectionSymbol?: string
imageUrl?: string imageUrl?: string
animationUrl?: string animationUrl?: string
mediaType?: MediaType
marketplace?: Markets marketplace?: Markets
name?: string name?: string
priceInfo: PriceInfo priceInfo: PriceInfo
......
import { NftActivityType, NftStandard, OrderStatus } from 'graphql/data/__generated__/types-and-hooks' import { MediaType, NftActivityType, NftStandard, OrderStatus } from 'graphql/data/__generated__/types-and-hooks'
import { ActivityEvent, CollectionInfoForAsset, GenieAsset, Markets, WalletAsset } from 'nft/types' import { ActivityEvent, CollectionInfoForAsset, GenieAsset, Markets, WalletAsset } from 'nft/types'
export const TEST_NFT_ASSET: GenieAsset = { export const TEST_NFT_ASSET: GenieAsset = {
...@@ -8,6 +8,7 @@ export const TEST_NFT_ASSET: GenieAsset = { ...@@ -8,6 +8,7 @@ export const TEST_NFT_ASSET: GenieAsset = {
collectionName: 'Azuki', collectionName: 'Azuki',
imageUrl: imageUrl:
'https://cdn.center.app/1/0xED5AF388653567Af2F388E6224dC7C4b3241C544/3318/50ed67ad647d0aa0cad0b830d136a677efc2fb72a44587bc35f2a5fb334a7fdf.png', 'https://cdn.center.app/1/0xED5AF388653567Af2F388E6224dC7C4b3241C544/3318/50ed67ad647d0aa0cad0b830d136a677efc2fb72a44587bc35f2a5fb334a7fdf.png',
mediaType: MediaType.Image,
marketplace: Markets.Opensea, marketplace: Markets.Opensea,
name: 'Azuki #3318', name: 'Azuki #3318',
priceInfo: { priceInfo: {
...@@ -33,6 +34,108 @@ export const TEST_NFT_ASSET: GenieAsset = { ...@@ -33,6 +34,108 @@ export const TEST_NFT_ASSET: GenieAsset = {
creator: {}, creator: {},
} }
export const TEST_VIDEO_NFT_ASSET: GenieAsset = {
id: 'TmZ0QXNzZXQ6MHg0ZTFmNDE2MTNjOTA4NGZkYjllMzRlMTFmYWU5NDEyNDI3NDgwZTU2XzcyMDI=',
address: '0x6c9369dc930fd794ad0af7511f483d936a2ef7f3',
notForSale: false,
collectionName: 'Terraforms by Mathcastles',
imageUrl:
'https://i.seadn.io/gae/tkDbNhjjBZV2PmYaJbJOOigywZCrlcyGRxeQFkZS1YZyihyG5GoWNWj3N9f1T7YVuaxOqdxhfJylC9ejtoCvdgBE932vd7jorVqA?w=500&auto=format',
animationUrl: 'https://openseauserdata.com/files/5af92728200027caa4f3f5ae87a486a7.mp4',
mediaType: MediaType.Video,
marketplace: Markets.Opensea,
name: 'Aku Chapter IV: Aku x Ady #884',
priceInfo: {
ETHPrice: '1295000000000000000',
baseAsset: 'ETH',
baseDecimals: '18',
basePrice: '1295000000000000000',
},
susFlag: false,
tokenId: '1455',
tokenType: NftStandard.Erc721,
collectionIsVerified: false,
totalCount: 9910,
rarity: {
primaryProvider: 'Rarity Sniper',
providers: [
{
rank: 7079,
provider: 'Rarity Sniper',
},
],
},
creator: {},
}
export const TEST_AUDIO_NFT_ASSET: GenieAsset = {
id: 'TmZ0QXNzZXQ6MHg0ZTFmNDE2MTNjOTA4NGZkYjllMzRlMTFmYWU5NDEyNDI3NDgwZTU2XzcyMDI=',
address: '0x37a03d4af1d7046d1126987b20117a0fdcbf6535',
notForSale: false,
collectionName: 'Snoop Dogg on Sound XYZ',
imageUrl:
'https://i.seadn.io/gae/Kze9SBqn_6O0qrHKxspo1gRkkDV2A5EmTeWtvdS-dNxBsvi_wPXUYjc6De0sUC-DYzL093102mUftenWxwWuTelqsdw-ngoBC3o2XFU?w=500&auto=format',
animationUrl: 'https://openseauserdata.com/files/4a22253e44e10baa11484a2e43efefda.mp3',
mediaType: MediaType.Audio,
marketplace: Markets.Opensea,
name: 'Death Row Session: Vol. 2 (420 Edition) #320',
priceInfo: {
ETHPrice: '1295000000000000000',
baseAsset: 'ETH',
baseDecimals: '18',
basePrice: '1295000000000000000',
},
susFlag: false,
tokenId: '680564733841876926926749214863536423232',
tokenType: NftStandard.Erc721,
collectionIsVerified: false,
totalCount: 9910,
rarity: {
primaryProvider: 'Rarity Sniper',
providers: [
{
rank: 7079,
provider: 'Rarity Sniper',
},
],
},
creator: {},
}
export const TEST_EMBEDDED_NFT_ASSET: GenieAsset = {
id: 'TmZ0QXNzZXQ6MHg0ZTFmNDE2MTNjOTA4NGZkYjllMzRlMTFmYWU5NDEyNDI3NDgwZTU2XzcyMDI=',
address: '0x4e1f41613c9084fdb9e34e11fae9412427480e56',
notForSale: false,
collectionName: 'Terraforms by Mathcastles',
imageUrl:
'https://cdn.center.app/v2/1/06ff92279474add6ce06176e2a65447396edf786d169d8ccc03fddfa45ce004f/bb01f8a2f093ea4619498dae58fc19e5ba3fa38a84cabf92948994609489d566.png',
animationUrl: 'https://tokens.mathcastles.xyz/terraforms/token-html/7202',
mediaType: MediaType.Raw,
marketplace: Markets.Opensea,
name: 'Level 13 at {28, 3}',
priceInfo: {
ETHPrice: '1295000000000000000',
baseAsset: 'ETH',
baseDecimals: '18',
basePrice: '1295000000000000000',
},
susFlag: false,
tokenId: '7202',
tokenType: NftStandard.Erc721,
collectionIsVerified: false,
totalCount: 9910,
rarity: {
primaryProvider: 'Rarity Sniper',
providers: [
{
rank: 7079,
provider: 'Rarity Sniper',
},
],
},
creator: { address: '0xe72eb31b59f85b19499a0f3b3260011894fa0d65' },
}
export const TEST_NFT_WALLET_ASSET: WalletAsset = { export const TEST_NFT_WALLET_ASSET: WalletAsset = {
id: 'TmZ0QXNzZXQ6RVRIRVJFVU1fMHgyOTY1MkMyZTlEMzY1NjQzNEJjODEzM2M2OTI1OEM4ZDA1MjkwZjQxXzIzNTk=', id: 'TmZ0QXNzZXQ6RVRIRVJFVU1fMHgyOTY1MkMyZTlEMzY1NjQzNEJjODEzM2M2OTI1OEM4ZDA1MjkwZjQxXzIzNTk=',
imageUrl: 'https://c.neevacdn.net/image/upload/xyz/T96PksTnWGNh79CrzLn-zpYfqRWtD5wME0MBPL_Md6Q.png', imageUrl: 'https://c.neevacdn.net/image/upload/xyz/T96PksTnWGNh79CrzLn-zpYfqRWtD5wME0MBPL_Md6Q.png',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment