From c3bac3d447f8aff54f9257002aca62aaab9a2153 Mon Sep 17 00:00:00 2001
From: gomes <17035424+gomesalexandre@users.noreply.github.com>
Date: Mon, 29 Jul 2024 02:18:20 +0300
Subject: [PATCH] fix: fallback icon for custom token import step (#7429)
* chore: zerion market data wip
* chore: wire up token price on import
* chore: filter by alchemy supported chainIds
* chore: hide fiat on input when not available
* chore: handle no fiat data in quote tag
* chore: more missing fiat handling
* chore: even more missing fiat handling
* feat: handle custom asset view
* fix: asset selection
* fix: market data selector
* feat: handle JIT market data fetching
* chore: first pass address review feedback
* chore: first pass kevs review feedback
* chore: 2nd pass kevs review feedback
* fix: build lint
* chore: remove JIT market data logic
* chore: remove custom asset prop
* chore: lint
* fix: ratio calc without market data
* feat: improve `` types
* fix: derp
* fix: more derp
* fix: more more derp
* fix: derpy derp derp
* fix: last derp?
* fix: actually last derp fix
* feat: pre-rebase mergefixes
---------
Co-authored-by: Apotheosis <97164662+0xApotheosis@users.noreply.github.com>
Co-authored-by: Apotheosis <0xapotheosis@gmail.com>
---
src/components/AssetIcon.tsx | 93 ++++++++++++-------
.../components/AssetMenuButton.tsx | 9 +-
src/components/ChainMenu.tsx | 4 +-
.../components/AssetSummaryStep.tsx | 4 +-
.../TradeAssetSearch/Chains/ChainCard.tsx | 1 +
.../components/CustomAssetAcknowledgement.tsx | 2 +-
.../components/GroupedAssetRow.tsx | 5 +-
.../TransactionDetails/TransferColumn.tsx | 2 +-
.../components/AssetTransfer.tsx | 2 +-
.../components/AssetsTransfers.tsx | 6 +-
.../Overview/ThorchainSaversEmpty.tsx | 12 ++-
.../ReusableLpStatus/TransactionRow.tsx | 6 +-
12 files changed, 86 insertions(+), 60 deletions(-)
diff --git a/src/components/AssetIcon.tsx b/src/components/AssetIcon.tsx
index 6c1559c3f3a..d529ca95ece 100644
--- a/src/components/AssetIcon.tsx
+++ b/src/components/AssetIcon.tsx
@@ -2,6 +2,7 @@ import type { AvatarProps } from '@chakra-ui/react'
import { Avatar, Center, Flex, useColorModeValue } from '@chakra-ui/react'
import type { AssetId } from '@shapeshiftoss/caip'
import { fromAssetId } from '@shapeshiftoss/caip'
+import type { Asset } from '@shapeshiftoss/types'
import { memo, useMemo } from 'react'
import { getChainAdapterManager } from 'context/PluginProvider/chainAdapterSingleton'
import { selectAssetById, selectFeeAssetById } from 'state/slices/selectors'
@@ -23,34 +24,58 @@ export const sansNotchBottom =
'polygon( 29.875% 95.781%,29.875% 95.781%,32.106% 96.7%,34.39% 97.513%,36.724% 98.218%,39.105% 98.81%,41.529% 99.287%,43.995% 99.646%,46.498% 99.882%,49.036% 99.994%,51.605% 99.977%,54.203% 99.828%,54.203% 99.828%,61.486% 98.674%,68.384% 96.495%,74.816% 93.377%,80.7% 89.403%,85.955% 84.66%,90.5% 79.232%,94.254% 73.203%,97.135% 66.658%,99.062% 59.682%,99.953% 52.359%,99.953% 52.359%,100.006% 49.623%,99.913% 46.921%,99.679% 44.257%,99.307% 41.634%,98.801% 39.057%,98.164% 36.528%,97.401% 34.053%,96.516% 31.635%,95.511% 29.277%,94.391% 26.984%,94.391% 26.984%,94.286% 26.814%,94.163% 26.66%,94.022% 26.523%,93.867% 26.405%,93.699% 26.307%,93.521% 26.23%,93.335% 26.175%,93.143% 26.143%,92.947% 26.137%,92.75% 26.156%,92.75% 26.156%,82.77% 28.407%,73.334% 31.927%,64.536% 36.619%,56.474% 42.387%,49.244% 49.135%,42.943% 56.766%,37.667% 65.185%,33.512% 74.295%,30.575% 84%,28.953% 94.203%,28.953% 94.203%,28.947% 94.403%,28.967% 94.6%,29.01% 94.791%,29.076% 94.973%,29.164% 95.146%,29.273% 95.308%,29.401% 95.456%,29.547% 95.588%,29.711% 95.702%,29.891% 95.797%,29.875% 95.781% );'
type AssetIconProps = {
- assetId?: AssetId
// Show the network icon instead of the asset icon e.g OP icon instead of ETH for Optimism native asset
showNetworkIcon?: boolean
-} & AvatarProps
+} & (
+ | {
+ assetId: AssetId
+ asset?: undefined
+ src?: undefined
+ icon?: undefined
+ }
+ | {
+ asset: Asset
+ assetId?: undefined
+ src?: undefined
+ icon?: undefined
+ }
+ | {
+ src: string | undefined
+ assetId?: undefined
+ asset?: undefined
+ icon?: undefined
+ }
+ | {
+ icon: JSX.Element
+ src?: undefined
+ assetId?: undefined
+ asset?: undefined
+ }
+) &
+ AvatarProps
// @TODO: this will be replaced with whatever we do for icons later
// The icon prop is used as the placeholder while the icon loads, or if it fails to load.
// Either src or assetId can be passed, if both are passed src takes precedence
type AssetWithNetworkProps = {
- assetId: AssetId
+ asset: Asset
showNetworkIcon?: boolean
} & AvatarProps
const AssetWithNetwork: React.FC = ({
- assetId,
+ asset,
icon,
src,
showNetworkIcon = true,
size,
...rest
}) => {
- const asset = useAppSelector(state => selectAssetById(state, assetId ?? ''))
- const feeAsset = useAppSelector(state => selectFeeAssetById(state, assetId))
- const showNetwork = feeAsset?.networkIcon || asset?.assetId !== feeAsset?.assetId
- const iconSrc = src ?? asset?.icon
+ const feeAsset = useAppSelector(state => selectFeeAssetById(state, asset.assetId))
+ const showNetwork = feeAsset?.networkIcon || asset.assetId !== feeAsset?.assetId
+ const iconSrc = src ?? asset.icon
// We should only show the fallback if the asset doesn't have an icon/icons
// Failure to check this means we would lose loading FOX icon functionality
- const showFallback = !asset?.icon && !asset?.icons?.length
+ const showFallback = !asset.icon && !asset.icons?.length
return (
@@ -70,7 +95,7 @@ const AssetWithNetwork: React.FC = ({
)}
= ({
)
}
-export const AssetIcon = memo(({ assetId, showNetworkIcon, src, ...rest }: AssetIconProps) => {
- const asset = useAppSelector(state => selectAssetById(state, assetId ?? ''))
- const assetIconBg = useColorModeValue('gray.200', 'gray.700')
- const assetIconColor = useColorModeValue('text.subtle', 'text.subtle')
+export const AssetIcon = memo(
+ ({ assetId: _assetId, asset: _asset, showNetworkIcon, src, ...rest }: AssetIconProps) => {
+ const asset = useAppSelector(state =>
+ _asset ? _asset : selectAssetById(state, _assetId ?? ''),
+ )
+ const assetId = _assetId ?? asset?.assetId
+ const assetIconBg = useColorModeValue('gray.200', 'gray.700')
+ const assetIconColor = useColorModeValue('text.subtle', 'text.subtle')
- const chainAdapterManager = getChainAdapterManager()
- const chainId = assetId && fromAssetId(assetId).chainId
- const nativeAssetId = chainAdapterManager.get(chainId ?? '')?.getFeeAssetId()
- const foxIcon = useMemo(() => , [assetIconColor])
+ const chainAdapterManager = getChainAdapterManager()
+ const chainId = assetId && fromAssetId(assetId).chainId
+ const nativeAssetId = chainAdapterManager.get(chainId ?? '')?.getFeeAssetId()
+ const foxIcon = useMemo(
+ () => ,
+ [assetIconColor],
+ )
- if (assetId === nativeAssetId && asset?.networkIcon && showNetworkIcon) {
- return
- }
+ if (!asset) return
- if (assetId) {
- if (asset?.icons?.length) {
+ if (assetId === nativeAssetId && asset.networkIcon && showNetworkIcon) {
+ return
+ }
+
+ if (asset.icons?.length) {
return (
{asset.icons.map((iconSrc, i) => (
@@ -108,15 +141,7 @@ export const AssetIcon = memo(({ assetId, showNetworkIcon, src, ...rest }: Asset
}
return (
-
+
)
- }
-
- return
-})
+ },
+)
diff --git a/src/components/AssetSelection/components/AssetMenuButton.tsx b/src/components/AssetSelection/components/AssetMenuButton.tsx
index 7f530bf5969..cf9bc7db55b 100644
--- a/src/components/AssetSelection/components/AssetMenuButton.tsx
+++ b/src/components/AssetSelection/components/AssetMenuButton.tsx
@@ -30,11 +30,10 @@ export const AssetMenuButton = ({
const asset = useAppSelector(state => selectAssetById(state, assetId ?? ''))
const icon = useMemo(() => {
- return asset?.icons ? (
-
- ) : (
-
- )
+ if (asset?.icons)
+ return
+ if (assetId) return
+ return null
}, [asset?.icons, assetId, showNetworkIcon])
const handleAssetClick = useCallback(() => {
diff --git a/src/components/ChainMenu.tsx b/src/components/ChainMenu.tsx
index 08f273b85eb..b189353a000 100644
--- a/src/components/ChainMenu.tsx
+++ b/src/components/ChainMenu.tsx
@@ -29,7 +29,7 @@ export type ChainMenuProps = {
onMenuOptionClick: (chainId: T) => void
}
-export const ChainIcon = (props: { chainId: ChainId } & AvatarProps) => {
+export const ChainIcon = (props: { chainId: ChainId } & Omit) => {
const { chainId, avatarProps } = useMemo(() => {
const { chainId, ...avatarProps } = props
return { chainId, avatarProps }
@@ -43,6 +43,8 @@ export const ChainIcon = (props: { chainId: ChainId } & AvatarProps) => {
return feeAssetId
}, [chainId])
+ if (!feeAssetId) return null
+
return
}
diff --git a/src/components/MultiHopTrade/components/MultiHopTradeConfirm/components/AssetSummaryStep.tsx b/src/components/MultiHopTrade/components/MultiHopTradeConfirm/components/AssetSummaryStep.tsx
index c77721be519..23a08753f1d 100644
--- a/src/components/MultiHopTrade/components/MultiHopTradeConfirm/components/AssetSummaryStep.tsx
+++ b/src/components/MultiHopTrade/components/MultiHopTradeConfirm/components/AssetSummaryStep.tsx
@@ -56,8 +56,8 @@ export const AssetSummaryStep = ({
}, [asset.chainId])
const assetIcon = useMemo(() => {
- return
- }, [asset.icon])
+ return
+ }, [asset.assetId])
return (
= memo(({ chainId, isActive, onClick }) => {
const feeAssetId = chainIdToFeeAssetId(chainId)
+ if (!feeAssetId) throw new Error(`feeAssetId not found for chainId ${chainId}`)
const feeAsset = useAppSelector(state => selectAssetById(state, feeAssetId ?? ''))
if (!feeAsset) throw new Error(`Fee asset not found for AssetId ${feeAssetId}`)
diff --git a/src/components/TradeAssetSearch/components/CustomAssetAcknowledgement.tsx b/src/components/TradeAssetSearch/components/CustomAssetAcknowledgement.tsx
index 697ed9618a5..754160ad162 100644
--- a/src/components/TradeAssetSearch/components/CustomAssetAcknowledgement.tsx
+++ b/src/components/TradeAssetSearch/components/CustomAssetAcknowledgement.tsx
@@ -102,7 +102,7 @@ export const CustomAssetAcknowledgement: React.FC
-
+
-
+
-
+
{
/>
-
+
= ({ index, compactMode
direction={index === 0 ? 'row' : 'row-reverse'}
textAlign={index === 0 ? 'left' : 'right'}
>
-
+
= ({
>
{singleAsset ? (
<>
-
+
{
+ if (!asset) return
+
return (
{bnOrZero(cryptoBalance).eq(0) && assetSupportsBuy}
-
+
)
}, [
- asset?.assetId,
- assetSupportsBuy,
+ asset,
cryptoBalance,
- handleAssetBuyClick,
+ assetSupportsBuy,
needAssetTranslation,
- onClick,
+ handleAssetBuyClick,
translate,
hasAccounts,
+ onClick,
])
const emptyOverviewAssets = useMemo(() => (asset ? [asset] : []), [asset])
diff --git a/src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx b/src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx
index 45433deaffb..9375ff32594 100644
--- a/src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx
+++ b/src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx
@@ -410,15 +410,15 @@ export const TransactionRow: React.FC = ({
{' '}
- {isSymWithdraw && (
+ {isSymWithdraw && poolAsset && (
// Symmetrical withdrawals withdraw both asset amounts in a single TX.
// In this case, we want to show the pool asset amount in additional to the rune amount for the user
<>
-
+
{' '}
>
)}