Skip to content

Commit

Permalink
fix: [CM-683][Sale Widget] Fallback token images (#1825)
Browse files Browse the repository at this point in the history
  • Loading branch information
jhesgodi authored and sharif9876 committed May 31, 2024
1 parent 858d53c commit 6ab1901
Show file tree
Hide file tree
Showing 11 changed files with 104 additions and 77 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"eslint": "^8.40.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-config-airbnb-typescript": "^17.0.0",
"eslint-plugin-react-refresh": "latest",
"http-server": "^14.1.1",
"husky": "^8.0.3",
"lint-staged": "^13.2.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { MenuItem, AllIconKeys } from '@biom3/react';
import { useTranslation } from 'react-i18next';
import { useMemo, useState } from 'react';
import { TokenImage } from 'components/TokenImage/TokenImage';

export interface CoinSelectorOptionProps {
testId?: string;
Expand All @@ -19,23 +19,14 @@ export interface CoinSelectorOptionProps {
export function CoinSelectorOption({
onClick, icon, name, symbol, balance, defaultTokenImage, testId, id,
}: CoinSelectorOptionProps) {
const [iconError, setIconError] = useState<boolean>(false);
const { t } = useTranslation();
const tokenUrl = useMemo(
() => ((!icon || iconError) ? defaultTokenImage : icon),
[icon, iconError, defaultTokenImage],
);

return (
<MenuItem testId={`${testId}-coin-selector__option-${id}`} emphasized size="small" onClick={onClick}>
<MenuItem.FramedImage
circularFrame
use={(
<img
src={tokenUrl}
alt={name}
onError={() => setIconError(true)}
/>
<TokenImage src={icon} name={name} defaultImage={defaultTokenImage} />
)}
/>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import {
import { useMemo, useState } from 'react';
import { Environment } from '@imtbl/config';
import { WidgetTheme } from '@imtbl/checkout-sdk';
import { TokenImage } from 'components/TokenImage/TokenImage';
import { FormControlWrapper } from '../FormControlWrapper/FormControlWrapper';
import { CoinSelector } from '../../CoinSelector/CoinSelector';
import { CoinSelectorOptionProps } from '../../CoinSelector/CoinSelectorOption';
import { getDefaultTokenImage } from '../../../lib/utils';

interface SelectFormProps {
testId: string;
Expand Down Expand Up @@ -41,7 +41,6 @@ export function SelectForm({
theme = WidgetTheme.DARK,
}: SelectFormProps) {
const [coinSelectorOpen, setCoinSelectorOpen] = useState<boolean>(false);
const [iconError, setIconError] = useState<boolean>(false);
const coinSelectorOptions = useMemo(() => options.map((option) => ({
...option,
testId,
Expand All @@ -59,10 +58,6 @@ export function SelectForm({
};

const filteredOption = options?.find((o) => o.id === selectedOption) as CoinSelectorOptionProps ?? selectedOption;
const tokenUrl = useMemo(() => {
if (typeof filteredOption === 'undefined') return '';
return iconError ? getDefaultTokenImage(environment, theme) : filteredOption.icon;
}, [filteredOption, environment, theme, iconError]);

return (
<Box>
Expand Down Expand Up @@ -103,10 +98,11 @@ export function SelectForm({
{filteredOption.icon && (
<Select.Option.FramedImage
use={(
<img
src={tokenUrl}
alt={filteredOption.id}
onError={() => setIconError(true)}
<TokenImage
environment={environment}
theme={theme}
src={filteredOption.icon}
name={filteredOption.name}
/>
)}
circularFrame
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { useMemo, useState } from 'react';
import { Environment } from '@imtbl/config';
import { getDefaultTokenImage } from 'lib/utils';
import { WidgetTheme } from '@imtbl/checkout-sdk';

type ImageProps = {
name?: string;
src?: string;
theme?: WidgetTheme;
environment?: Environment;
defaultImage?: string;
} & (
| { defaultImage: string; theme?: WidgetTheme; environment?: Environment }
| { defaultImage?: never; theme: WidgetTheme; environment: Environment }
);

export function TokenImage({
src,
name,
environment,
theme,
defaultImage,
...forwardedProps
}: ImageProps) {
const [error, setError] = useState<boolean>(false);
const url = useMemo(
() => (!src || error
? defaultImage
|| (theme && getDefaultTokenImage(environment, theme))
|| ''
: src),
[src, error],
);

return (
<img
src={url}
alt={name}
onError={() => setError(true)}
{...forwardedProps}
/>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import {
} from '@biom3/react';
import { UserJourney, useAnalytics } from 'context/analytics-provider/SegmentAnalyticsProvider';
import { Transaction } from 'lib/clients/checkoutApiType';
import { MouseEvent, useMemo, useState } from 'react';
import { MouseEvent, useMemo } from 'react';
import { TokenImage } from 'components/TokenImage/TokenImage';
import { Environment } from '@imtbl/config';
import { containerStyles } from './transactionItemStyles';
import { TransactionDetails } from './TransactionDetails';
Expand Down Expand Up @@ -38,11 +39,6 @@ export function TransactionItem({
environment,
}: TransactionItemProps) {
const { track } = useAnalytics();
const [iconError, setIconError] = useState<boolean>(false);
const tokenUrl = useMemo(
() => ((!icon || iconError) ? defaultTokenImage : icon),
[icon, iconError, defaultTokenImage],
);
const txnDetailsLink = useMemo(() => `${details.link}${details.hash}`, [details]);

const handleDetailsLinkClick = (
Expand Down Expand Up @@ -89,10 +85,10 @@ export function TransactionItem({
<MenuItem.FramedImage
circularFrame
use={(
<img
src={tokenUrl}
alt={label}
onError={() => setIconError(true)}
<TokenImage
src={icon}
name={label}
defaultImage={defaultTokenImage}
/>
)}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ import {
} from '@biom3/react';
import { UserJourney, useAnalytics } from 'context/analytics-provider/SegmentAnalyticsProvider';
import { Transaction, TransactionStatus } from 'lib/clients/checkoutApiType';
import { useContext, useMemo, useState } from 'react';
import { useContext, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { BridgeWidgetViews } from 'context/view-context/BridgeViewContextTypes';
import { ViewActions, ViewContext } from 'context/view-context/ViewContext';
import { TokenImage } from 'components/TokenImage/TokenImage';
import { Environment } from '@imtbl/config';
import { actionsContainerStyles, actionsLayoutStyles, containerStyles } from './transactionItemStyles';
import { TransactionDetails } from './TransactionDetails';
Expand All @@ -39,11 +40,6 @@ export function TransactionItemWithdrawPending({
const { viewDispatch } = useContext(ViewContext);
const { track } = useAnalytics();
const translation = useTranslation();
const [iconError, setIconError] = useState<boolean>(false);
const tokenUrl = useMemo(
() => ((!icon || iconError) ? defaultTokenImage : icon),
[icon, iconError, defaultTokenImage],
);
const dateNowUnixMs = useMemo(() => new Date().getTime(), []);
const withdrawalReadyDate = useMemo(
() => (transaction.details.current_status.withdrawal_ready_at
Expand Down Expand Up @@ -160,10 +156,10 @@ export function TransactionItemWithdrawPending({
<MenuItem.FramedImage
circularFrame
use={(
<img
src={tokenUrl}
alt={label}
onError={() => setIconError(true)}
<TokenImage
src={icon}
name={label}
defaultImage={defaultTokenImage}
/>
)}
/>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import {
Box,
Heading, MenuItem, MenuItemSize, prettyFormatNumber,
Heading,
MenuItem,
MenuItemSize,
prettyFormatNumber,
} from '@biom3/react';
import { TransactionRequirement } from '@imtbl/checkout-sdk';
import {
calculateCryptoToFiat,
getDefaultTokenImage,
tokenValueFormat,
} from 'lib/utils';
import { calculateCryptoToFiat, tokenValueFormat } from 'lib/utils';
import { TokenImage } from 'components/TokenImage/TokenImage';
import { useTranslation } from 'react-i18next';
import { ReactElement } from 'react';

Expand Down Expand Up @@ -70,9 +70,11 @@ export function CoinsDrawerItem<
circularFrame
alt={token.name}
use={(
<img
src={token.icon ?? getDefaultTokenImage(environment, theme)}
alt={token.name}
<TokenImage
environment={environment}
theme={theme}
name={token.name}
src={token.icon}
/>
)}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { SaleItem } from '@imtbl/checkout-sdk';
import { useTranslation } from 'react-i18next';
import { calculateCryptoToFiat, tokenValueFormat } from 'lib/utils';
import { ReactElement } from 'react';
import { TokenImage } from 'components/TokenImage/TokenImage';
import { OrderQuotePricing, FundingBalance } from '../types';

export interface OrderItemProps<
Expand Down Expand Up @@ -52,9 +53,7 @@ export function OrderItem<RC extends ReactElement | undefined = undefined>({
}}
>
<MenuItem.FramedImage
use={(
<img src={item.image} alt={item.name} />
)}
use={<TokenImage src={item.image} name={item.name} defaultImage={item.image} />}
/>
<MenuItem.Label>{item.name}</MenuItem.Label>
<MenuItem.Caption>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@ import {
} from '@biom3/react';
import { useTranslation } from 'react-i18next';
import {
calculateCryptoToFiat,
getDefaultTokenImage,
tokenValueFormat,
calculateCryptoToFiat, tokenValueFormat,
} from 'lib/utils';
import { TokenImage } from 'components/TokenImage/TokenImage';
import { FundingBalance } from '../types';
import { useSaleContext } from '../context/SaleContextProvider';

Expand Down Expand Up @@ -74,19 +73,18 @@ export function SelectCoinDropdown({
<MenuItem.FramedImage
circularFrame
use={(
<img
src={token.icon ?? getDefaultTokenImage(environment, theme)}
alt={token.name}
<TokenImage
environment={environment}
theme={theme}
name={token.name}
src={token.icon}
/>
)}
/>
<MenuItem.Label>
{t(
`views.ORDER_SUMMARY.orderReview.payWith.${balance.type}`,
{
symbol: token.symbol,
},
)}
{t(`views.ORDER_SUMMARY.orderReview.payWith.${balance.type}`, {
symbol: token.symbol,
})}
</MenuItem.Label>
<MenuItem.Caption rc={<Heading size="xSmall" />}>
{`${t('views.ORDER_SUMMARY.orderReview.balance', {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@ import {
IMTBLWidgetEvents, TokenFilterTypes, TokenInfo, WidgetTheme,
} from '@imtbl/checkout-sdk';
import { Environment } from '@imtbl/config';
import { TokenImage } from 'components/TokenImage/TokenImage';
import { ShowMenuItem } from './BalanceItemStyles';
import { BalanceInfo } from '../../functions/tokenBalances';
import { WalletContext } from '../../context/WalletContext';
import { orchestrationEvents } from '../../../../lib/orchestrationEvents';
import { getL1ChainId, getL2ChainId } from '../../../../lib/networkUtils';
import { formatZeroAmount, getDefaultTokenImage, tokenValueFormat } from '../../../../lib/utils';
import { formatZeroAmount, tokenValueFormat } from '../../../../lib/utils';
import { ConnectLoaderContext } from '../../../../context/connect-loader-context/ConnectLoaderContext';
import { isPassportProvider } from '../../../../lib/provider';
import { EventTargetContext } from '../../../../context/event-target-context/EventTargetContext';
Expand Down Expand Up @@ -43,16 +44,9 @@ export function BalanceItem({
const [onRampAllowedTokens, setOnRampAllowedTokens] = useState<TokenInfo[]>(
[],
);
const [iconError, setIconError] = useState<boolean>(false);

const isPassport = isPassportProvider(provider);

const tokenUrl = useMemo(() => {
if (!checkout) return '';
const environment = checkout?.config.environment ?? Environment.PRODUCTION;
return iconError ? getDefaultTokenImage(environment, theme) : balanceInfo.icon;
}, [balanceInfo.icon, checkout, theme, iconError]);

useEffect(() => {
const getOnRampAllowedTokens = async () => {
if (!checkout) return;
Expand Down Expand Up @@ -98,10 +92,11 @@ export function BalanceItem({
<MenuItem testId={`balance-item-${balanceInfo.symbol}`} emphasized>
<MenuItem.FramedImage
use={(
<img
src={tokenUrl}
alt={balanceInfo.symbol}
onError={() => setIconError(true)}
<TokenImage
theme={theme}
src={balanceInfo.icon}
name={balanceInfo.symbol}
environment={checkout?.config.environment ?? Environment.PRODUCTION}
/>
)}
circularFrame
Expand Down
10 changes: 10 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -15805,6 +15805,15 @@ __metadata:
languageName: node
linkType: hard

"eslint-plugin-react-refresh@npm:latest":
version: 0.4.7
resolution: "eslint-plugin-react-refresh@npm:0.4.7"
peerDependencies:
eslint: ">=7"
checksum: b2fe14d4ed158b6380ffd9831a5ebed4c79828ea806536d5db0aa8370f8a3878b198d77fc7da18bfd862cd9eb19ed4472cc9977f727f81679f80dcb48f8a3861
languageName: node
linkType: hard

"eslint-plugin-react@npm:^7.27.1, eslint-plugin-react@npm:^7.31.7":
version: 7.33.0
resolution: "eslint-plugin-react@npm:7.33.0"
Expand Down Expand Up @@ -28057,6 +28066,7 @@ __metadata:
eslint: ^8.40.0
eslint-config-airbnb: ^19.0.4
eslint-config-airbnb-typescript: ^17.0.0
eslint-plugin-react-refresh: latest
http-server: ^14.1.1
husky: ^8.0.3
lint-staged: ^13.2.0
Expand Down

0 comments on commit 6ab1901

Please sign in to comment.