mirror of
https://github.com/Permissionless-Software-Foundation/bch-dex-taker-v2.git
synced 2026-09-21 16:52:01 -07:00
fix(NFTs): Refine token metadata loading and caching
This commit is contained in:
@@ -10,7 +10,6 @@ import AsyncLoad from '../../../services/async-load'
|
||||
|
||||
function BuyButton (props) {
|
||||
const { token, appData, onSuccess } = props
|
||||
console.log('props: ', props)
|
||||
const [show, setShow] = useState(false) // show the modal
|
||||
const [onFetch, setOnFetch] = useState(false) // show the spinner
|
||||
const [error, setError] = useState(false) // show the error message
|
||||
|
||||
@@ -74,7 +74,8 @@ function NftsForSale (props) {
|
||||
return offer
|
||||
}
|
||||
}, [appData])
|
||||
// Function to process token metadata (iconUrl , userData).
|
||||
|
||||
// Function to process token metadata (iconUrl , userData , tokenData).
|
||||
const processOfferMetadata = useCallback(async (offer) => {
|
||||
try {
|
||||
// Token icon
|
||||
@@ -82,7 +83,15 @@ function NftsForSale (props) {
|
||||
offer.icon = offer.tokenIconUrl
|
||||
offer.iconAlreadyDownloaded = true
|
||||
offer.userData = JSON.parse(offer.userDataStr)
|
||||
offer.mutableFromBackend = true
|
||||
offer.mutableDataSource = 'backend'
|
||||
}
|
||||
// tokenData
|
||||
if (offer.tokenData) {
|
||||
offer.tokenDataFromBackend = true
|
||||
offer.tokenDataSource = 'backend'
|
||||
}
|
||||
|
||||
return offer
|
||||
} catch (error) {
|
||||
return offer
|
||||
@@ -126,8 +135,10 @@ function NftsForSale (props) {
|
||||
for (let i = 0; i < tokens.length; i++) {
|
||||
const thisToken = tokens[i]
|
||||
|
||||
// data does not need to be downloaded, so continue with the next one
|
||||
if (thisToken.dataAlreadyDownloaded) continue
|
||||
// Skip if already has tokenData (from backend or cache)
|
||||
if (thisToken.dataAlreadyDownloaded || thisToken.tokenData) {
|
||||
continue
|
||||
}
|
||||
|
||||
// Try to get token data.
|
||||
const tokenData = await appData.wallet.getTokenData(thisToken.tokenId)
|
||||
@@ -135,6 +146,7 @@ function NftsForSale (props) {
|
||||
if (tokenData) {
|
||||
// Set data to the token object , this can be used to display the token name in the token card component.
|
||||
thisToken.tokenData = tokenData
|
||||
thisToken.tokenDataSource = 'blockchain'
|
||||
}
|
||||
|
||||
// Mark token to prevent fetch token data again.
|
||||
@@ -195,6 +207,7 @@ function NftsForSale (props) {
|
||||
// Set the icon url to the token , this can be used to display the icon in the token card component.
|
||||
thisToken.icon = iconUrl
|
||||
thisToken.userData = userData
|
||||
thisToken.mutableDataSource = 'blockchain'
|
||||
}
|
||||
|
||||
// Mark token to prevent fetch token icon again.
|
||||
@@ -210,15 +223,23 @@ function NftsForSale (props) {
|
||||
// Check if token data exists in the cache and add it to the tokens object.
|
||||
const reviewNftCachedData = useCallback(async (offers) => {
|
||||
const cacheData = appData.nftForSaleCacheData
|
||||
console.log(`Token data from cache: ${JSON.stringify(cacheData, null, 2)}`)
|
||||
// console.log(`Token data from cache: ${JSON.stringify(cacheData, null, 2)}`)
|
||||
|
||||
// Map all offers
|
||||
for (let i = 0; i < offers.length; i++) {
|
||||
const thisToken = offers[i]
|
||||
// console.log(`Review offers:`,thisToken)
|
||||
|
||||
const cacheToken = cacheData[thisToken.tokenId]
|
||||
// If cache data exists, add it to the token object
|
||||
if (cacheToken) {
|
||||
thisToken.tokenData = cacheToken.tokenData
|
||||
// Only use cache if backend didn't provide the data
|
||||
if (cacheToken && !thisToken.icon) {
|
||||
thisToken.icon = cacheToken.tokenIcon
|
||||
thisToken.mutableDataSource = 'cache'
|
||||
}
|
||||
if (cacheToken && !thisToken.tokenData) {
|
||||
thisToken.tokenData = cacheToken.tokenData
|
||||
thisToken.tokenDataSource = 'cache'
|
||||
}
|
||||
}
|
||||
}, [appData])
|
||||
@@ -228,13 +249,17 @@ function NftsForSale (props) {
|
||||
// Map all offers
|
||||
for (let i = 0; i < offers.length; i++) {
|
||||
const thisToken = offers[i]
|
||||
// save token icon and token data in cache
|
||||
const newTokenCacheData = {
|
||||
tokenIcon: thisToken.icon,
|
||||
tokenData: thisToken.tokenData
|
||||
}
|
||||
|
||||
console.log('newTokenCacheData: ', newTokenCacheData)
|
||||
// Only cache if we fetched it ourselves (not from backend)
|
||||
// Backend data is already "cached" server-side, no need to duplicate
|
||||
|
||||
if (thisToken.tokenDataFromBackend && thisToken.mutableFromBackend) continue
|
||||
|
||||
const newTokenCacheData = {}
|
||||
|
||||
if (!thisToken.tokenDataFromBackend) newTokenCacheData.tokenData = thisToken.tokenData
|
||||
if (!thisToken.mutableFromBackend) newTokenCacheData.tokenIcon = thisToken.icon
|
||||
|
||||
appData.updateNFTCachedData(thisToken.tokenId, newTokenCacheData)
|
||||
}
|
||||
}, [appData])
|
||||
|
||||
@@ -13,6 +13,7 @@ import BuyButton from './buy-button'
|
||||
import SellerProfile from './seller-profile'
|
||||
function TokenCard (props) {
|
||||
const { token, appData, handleRefresh, hideBuyBtn } = props
|
||||
console.log('token', token)
|
||||
const [icon, setIcon] = useState(token.icon)
|
||||
const [tokenData, setTokenData] = useState(token.tokenData)
|
||||
|
||||
|
||||
@@ -40,6 +40,29 @@ function NFTForSale (props) {
|
||||
}
|
||||
}, [appData])
|
||||
|
||||
// Function to process token metadata (iconUrl , userData , tokenData).
|
||||
const processOfferMetadata = useCallback(async (offer) => {
|
||||
try {
|
||||
// Token icon
|
||||
if (offer.tokenIconUrl) {
|
||||
offer.icon = offer.tokenIconUrl
|
||||
offer.iconAlreadyDownloaded = true
|
||||
offer.userData = JSON.parse(offer.userDataStr)
|
||||
offer.mutableFromBackend = true
|
||||
offer.mutableDataSource = 'backend'
|
||||
}
|
||||
// tokenData
|
||||
if (offer.tokenData) {
|
||||
offer.tokenDataFromBackend = true
|
||||
offer.tokenDataSource = 'backend'
|
||||
}
|
||||
|
||||
return offer
|
||||
} catch (error) {
|
||||
return offer
|
||||
}
|
||||
}, [])
|
||||
|
||||
// Fetch offers
|
||||
const getNftOffers = useCallback(async (page = 0) => {
|
||||
try {
|
||||
@@ -57,7 +80,8 @@ function NFTForSale (props) {
|
||||
for (let i = 0; i < rawOffers.length; i++) {
|
||||
const offer = rawOffers[i]
|
||||
const processedOffer = await processTokenData(offer)
|
||||
processedOffers.push(processedOffer)
|
||||
const processedOfferMetadata = await processOfferMetadata(processedOffer)
|
||||
processedOffers.push(processedOfferMetadata)
|
||||
}
|
||||
|
||||
setOffersAreLoaded(true)
|
||||
@@ -68,7 +92,7 @@ function NFTForSale (props) {
|
||||
setOffersAreLoaded(true)
|
||||
throw err
|
||||
}
|
||||
}, [processTokenData, profileAddresses])
|
||||
}, [processTokenData, processOfferMetadata, profileAddresses])
|
||||
|
||||
// This function loads the token data .
|
||||
const lazyLoadTokenData = useCallback(async (tokens) => {
|
||||
@@ -78,8 +102,10 @@ function NFTForSale (props) {
|
||||
for (let i = 0; i < tokens.length; i++) {
|
||||
const thisToken = tokens[i]
|
||||
|
||||
// data does not need to be downloaded, so continue with the next one
|
||||
if (thisToken.dataAlreadyDownloaded) continue
|
||||
// Skip if already has tokenData (from backend or cache)
|
||||
if (thisToken.dataAlreadyDownloaded || thisToken.tokenData) {
|
||||
continue
|
||||
}
|
||||
|
||||
// Try to get token data.
|
||||
const tokenData = await appData.wallet.getTokenData(thisToken.tokenId)
|
||||
@@ -87,6 +113,7 @@ function NFTForSale (props) {
|
||||
if (tokenData) {
|
||||
// Set data to the token object , this can be used to display the token name in the token card component.
|
||||
thisToken.tokenData = tokenData
|
||||
thisToken.tokenDataSource = 'blockchain'
|
||||
}
|
||||
|
||||
// Mark token to prevent fetch token data again.
|
||||
@@ -146,6 +173,7 @@ function NFTForSale (props) {
|
||||
// Set the icon url to the token , this can be used to display the icon in the token card component.
|
||||
thisToken.icon = iconUrl
|
||||
thisToken.userData = userData
|
||||
thisToken.mutableDataSource = 'blockchain'
|
||||
}
|
||||
|
||||
// Mark token to prevent fetch token icon again.
|
||||
@@ -161,15 +189,23 @@ function NFTForSale (props) {
|
||||
// Check if token data exists in the cache and add it to the tokens object.
|
||||
const reviewNftCachedData = useCallback(async (offers) => {
|
||||
const cacheData = appData.nftForSaleCacheData
|
||||
console.log(`Token data from cache: ${JSON.stringify(cacheData, null, 2)}`)
|
||||
// console.log(`Token data from cache: ${JSON.stringify(cacheData, null, 2)}`)
|
||||
|
||||
// Map all offers
|
||||
for (let i = 0; i < offers.length; i++) {
|
||||
const thisToken = offers[i]
|
||||
// console.log(`Review offers:`,thisToken)
|
||||
|
||||
const cacheToken = cacheData[thisToken.tokenId]
|
||||
// If cache data exists, add it to the token object
|
||||
if (cacheToken) {
|
||||
thisToken.tokenData = cacheToken.tokenData
|
||||
// Only use cache if backend didn't provide the data
|
||||
if (cacheToken && !thisToken.icon) {
|
||||
thisToken.icon = cacheToken.tokenIcon
|
||||
thisToken.mutableDataSource = 'cache'
|
||||
}
|
||||
if (cacheToken && !thisToken.tokenData) {
|
||||
thisToken.tokenData = cacheToken.tokenData
|
||||
thisToken.tokenDataSource = 'cache'
|
||||
}
|
||||
}
|
||||
}, [appData])
|
||||
@@ -179,13 +215,17 @@ function NFTForSale (props) {
|
||||
// Map all offers
|
||||
for (let i = 0; i < offers.length; i++) {
|
||||
const thisToken = offers[i]
|
||||
// save token icon and token data in cache
|
||||
const newTokenCacheData = {
|
||||
tokenIcon: thisToken.icon,
|
||||
tokenData: thisToken.tokenData
|
||||
}
|
||||
|
||||
console.log('newTokenCacheData: ', newTokenCacheData)
|
||||
// Only cache if we fetched it ourselves (not from backend)
|
||||
// Backend data is already "cached" server-side, no need to duplicate
|
||||
|
||||
if (thisToken.tokenDataFromBackend && thisToken.mutableFromBackend) continue
|
||||
|
||||
const newTokenCacheData = {}
|
||||
|
||||
if (!thisToken.tokenDataFromBackend) newTokenCacheData.tokenData = thisToken.tokenData
|
||||
if (!thisToken.mutableFromBackend) newTokenCacheData.tokenIcon = thisToken.icon
|
||||
|
||||
appData.updateNFTCachedData(thisToken.tokenId, newTokenCacheData)
|
||||
}
|
||||
}, [appData])
|
||||
|
||||
Reference in New Issue
Block a user