Skip to content

Commit

Permalink
Use cdn for nft images
Browse files Browse the repository at this point in the history
  • Loading branch information
jorbuedo committed Nov 9, 2023
1 parent d3fcaa0 commit 845567b
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 74 deletions.
103 changes: 29 additions & 74 deletions apps/wallet-mobile/src/components/NftPreview/NftPreview.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,13 @@
import {isString} from '@yoroi/common'
import {Balance} from '@yoroi/types'
import React, {useEffect, useState} from 'react'
import {ErrorBoundary} from 'react-error-boundary'
import React from 'react'
import {Image, ImageResizeMode, ImageStyle, StyleProp, View} from 'react-native'
import SkeletonPlaceholder from 'react-native-skeleton-placeholder'
import {SvgUri} from 'react-native-svg'

import placeholder from '../../assets/img/nft-placeholder.png'
import {getNftFilenameMediaType, getNftMainImageMediaType, isSvgMediaType} from '../../yoroi-wallets/cardano/nfts'
import {useNativeAssetImage} from '../../yoroi-wallets/hooks'

export const NftPreview = ({
nft,
showPlaceholder,
style,
showThumbnail,
height,
width,
resizeMode,
blurRadius,
}: {
type NftPreviewProps = {
nft: Balance.TokenInfo
showPlaceholder?: boolean
style?: StyleProp<ImageStyle>
Expand All @@ -27,69 +16,35 @@ export const NftPreview = ({
width: number
resizeMode?: ImageResizeMode
blurRadius?: number
}) => {
const [error, setError] = useState(false)
const [loading, setLoading] = useState(true)
const uri = showThumbnail ? nft.icon : nft.image
const isUriSvg =
isString(uri) &&
(uri.toLowerCase().endsWith('.svg') ||
isSvgMediaType(getNftMainImageMediaType(nft)) ||
isSvgMediaType(getNftFilenameMediaType(nft, uri)))

const shouldShowPlaceholder = !isString(uri) || showPlaceholder || (isUriSvg && blurRadius !== undefined) || error
}

useEffect(() => {
setLoading(true)
}, [uri])
export const NftPreview = ({
nft,
showPlaceholder,
style,
height,
width,
resizeMode = 'contain',
blurRadius,
}: NftPreviewProps) => {
const {uri, isLoading, isError} = useNativeAssetImage({fingerprint: nft.fingerprint, width, height, kind: 'metadata'})

if (shouldShowPlaceholder) {
// Since SvgUri does not support blur radius, we show a placeholder
return <PlaceholderImage height={height} style={style} width={width} resizeMode={resizeMode} />
}
const shouldShowPlaceholder = !isString(uri) || showPlaceholder || isError

return (
<ErrorBoundary fallback={<PlaceholderImage height={height} style={style} width={width} resizeMode={resizeMode} />}>
<View style={{width, height, overflow: 'hidden'}}>
{loading ? (
<SkeletonPlaceholder enabled={true}>
<View style={{width, height}} />
</SkeletonPlaceholder>
) : null}

{isUriSvg ? (
<SvgUri
{...(width !== undefined ? {width} : undefined)}
height={height}
uri={uri}
style={style}
preserveAspectRatio="xMinYMin meet"
onError={() => setError(true)}
onLoad={() => setLoading(false)}
/>
) : (
<Image
blurRadius={blurRadius}
source={{uri}}
style={[style, {width, height}]}
resizeMode={resizeMode ?? 'contain'}
onError={() => setError(true)}
onLoadEnd={() => setLoading(false)}
/>
)}
</View>
</ErrorBoundary>
<View style={{width, height, overflow: 'hidden'}}>
{isLoading ? (
<SkeletonPlaceholder enabled={true}>
<View style={{width, height}} />
</SkeletonPlaceholder>
) : (
<Image
source={shouldShowPlaceholder ? placeholder : {uri}}
style={[style, {width, height}]}
resizeMode={resizeMode}
blurRadius={blurRadius}
/>
)}
</View>
)
}

const PlaceholderImage = ({
style,
width,
height,
resizeMode,
}: {
style?: StyleProp<ImageStyle>
height: number
width?: number
resizeMode?: ImageResizeMode
}) => <Image source={placeholder} style={[style, {width, height}]} resizeMode={resizeMode ?? 'contain'} />
37 changes: 37 additions & 0 deletions apps/wallet-mobile/src/yoroi-wallets/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {App, Balance} from '@yoroi/types'
import {Buffer} from 'buffer'
import * as React from 'react'
import {useCallback, useMemo} from 'react'
import Config from 'react-native-config'
import {
onlineManager,
QueryKey,
Expand Down Expand Up @@ -960,3 +961,39 @@ export function useHideBottomTabBar() {
return () => navigation.getParent()?.setOptions({tabBarStyle: true, tabBarVisible: undefined})
}, [navigation])
}

type NativeAssetImageRequest = {
networkId: NetworkId
fingerprint: Balance.TokenInfo['fingerprint']
width: string | number
height: string | number
kind?: 'logo' | 'metadata'
}
export const useNativeAssetImage = ({
networkId,
fingerprint,
width,
height,
kind = 'metadata',
}: NativeAssetImageRequest) => {
const network = networkId === 300 ? 'preprod' : 'mainnet'
const env = Config.BUILD_VARIANT === 'PROD' ? 'prod' : 'dev'
const query = useQuery({
staleTime: Infinity,
queryKey: ['native-asset-img', fingerprint, `${width}x${height}`],
queryFn: async () => {
const response = await fetch(
`https://${network}.cardano-nativeassets-${env}.emurgornd.com/${fingerprint}?width=${width}&height=${height}&kind=${kind}`,
)
if (!response.ok) {
throw new Error('Network response was not ok')
}
return `data:${response.headers['Content-Type']};base64,${await response.text()}`
},
})

return {
...query,
uri: query.data,
}
}

0 comments on commit 845567b

Please sign in to comment.