Commit 5e86cf7b authored by eddie's avatar eddie Committed by GitHub

fix: token img loading state (#6984)

* fix: token img loading state

* fix: nits

* fix: update snapshots

* fix: token logos in MP and tests

* fix: really weird visibility / tooltip bug

* fix: update snapshots
parent 83172dc5
import { ChainId, Currency } from '@uniswap/sdk-core'
import blankTokenUrl from 'assets/svg/blank_token.svg'
import { ReactComponent as UnknownStatus } from 'assets/svg/contract-interaction.svg'
import { LogoImage, MissingImageLogo } from 'components/Logo/AssetLogo'
import { MissingImageLogo } from 'components/Logo/AssetLogo'
import CurrencyLogo from 'components/Logo/CurrencyLogo'
import { Unicon } from 'components/Unicon'
import { getChainInfo } from 'constants/chainInfo'
import useTokenLogoSource from 'hooks/useAssetLogoSource'
......@@ -20,16 +21,16 @@ const DoubleLogoContainer = styled.div`
position: relative;
top: 0;
left: 0;
${LogoImage}:nth-child(n) {
img:nth-child(n) {
width: 19px;
height: 40px;
object-fit: cover;
}
${LogoImage}:nth-child(1) {
img:nth-child(1) {
border-radius: 20px 0 0 20px;
object-position: 0 0;
}
${LogoImage}:nth-child(2) {
img:nth-child(2) {
border-radius: 0 20px 20px 0;
object-position: 100% 0;
}
......@@ -66,6 +67,12 @@ const SquareChainLogo = styled.img`
width: 100%;
`
const CircleLogoImage = styled.img<{ size: string }>`
width: ${({ size }) => size};
height: ${({ size }) => size};
border-radius: 50%;
`
const L2LogoContainer = styled.div<{ $backgroundColor?: string }>`
background-color: ${({ $backgroundColor }) => $backgroundColor};
border-radius: 2px;
......@@ -109,18 +116,16 @@ export function PortfolioLogo({
<Unicon size={40} address={accountAddress} />
)
} else if (currencies && currencies.length) {
const logo1 = <LogoImage size={size} src={src ?? blankTokenUrl} onError={nextSrc} />
const logo2 = <LogoImage size={size} src={src2 ?? blankTokenUrl} onError={nextSrc2} />
const logo1 = <CircleLogoImage size={size} src={src ?? blankTokenUrl} onError={nextSrc} />
const logo2 = <CircleLogoImage size={size} src={src2 ?? blankTokenUrl} onError={nextSrc2} />
component =
currencies.length > 1 ? (
<DoubleLogoContainer style={style}>
{logo1}
{logo2}
</DoubleLogoContainer>
) : src ? (
logo1
) : currencies.length === 1 ? (
<CurrencyLogo currency={currencies[0]} size={size} />
) : (
<MissingImageLogo size={size}>
{currencies[0]?.symbol?.toUpperCase().replace('$', '').replace(/\s+/g, '').slice(0, 3)}
......@@ -130,11 +135,11 @@ export function PortfolioLogo({
component =
images.length > 1 ? (
<DoubleLogoContainer style={style}>
<LogoImage size={size} src={images[0]} />
<LogoImage size={size} src={images[images.length - 1]} />
<CircleLogoImage size={size} src={images[0]} />
<CircleLogoImage size={size} src={images[images.length - 1]} />
</DoubleLogoContainer>
) : (
<LogoImage size={size} src={images[0]} />
<CircleLogoImage size={size} src={images[0]} />
)
} else {
return <UnknownContract width={size} height={size} />
......
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`PortfolioLogo renders with L2 icon 1`] = `
.c3 {
width: 40px;
height: 40px;
border-radius: 50%;
}
.c1 {
display: -webkit-box;
display: -webkit-flex;
......@@ -21,18 +15,18 @@ exports[`PortfolioLogo renders with L2 icon 1`] = `
left: 0;
}
.c1 .c2:nth-child(n) {
.c1 img:nth-child(n) {
width: 19px;
height: 40px;
object-fit: cover;
}
.c1 .c2:nth-child(1) {
.c1 img:nth-child(1) {
border-radius: 20px 0 0 20px;
object-position: 0 0;
}
.c1 .c2:nth-child(2) {
.c1 img:nth-child(2) {
border-radius: 0 20px 20px 0;
object-position: 100% 0;
}
......@@ -43,12 +37,18 @@ exports[`PortfolioLogo renders with L2 icon 1`] = `
left: 0;
}
.c5 {
.c4 {
height: 14px;
width: 14px;
}
.c4 {
.c2 {
width: 40px;
height: 40px;
border-radius: 50%;
}
.c3 {
background-color: #0D111C;
border-radius: 2px;
height: 16px;
......@@ -79,20 +79,20 @@ exports[`PortfolioLogo renders with L2 icon 1`] = `
class="c1"
>
<img
class="c2 c3"
class="c2"
src="https://raw.githubusercontent.com/Uniswap/assets/master/blockchains/arbitrum/assets/0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1/logo.png"
/>
<img
class="c2 c3"
class="c2"
src="https://raw.githubusercontent.com/Uniswap/assets/master/blockchains/arbitrum/assets/0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8/logo.png"
/>
</div>
<div
class="c4"
class="c3"
>
<img
alt="chainLogo"
class="c5"
class="c4"
src="arbitrum_logo.svg"
/>
</div>
......@@ -101,12 +101,6 @@ exports[`PortfolioLogo renders with L2 icon 1`] = `
`;
exports[`PortfolioLogo renders without L2 icon 1`] = `
.c3 {
width: 40px;
height: 40px;
border-radius: 50%;
}
.c1 {
display: -webkit-box;
display: -webkit-flex;
......@@ -121,18 +115,18 @@ exports[`PortfolioLogo renders without L2 icon 1`] = `
left: 0;
}
.c1 .c2:nth-child(n) {
.c1 img:nth-child(n) {
width: 19px;
height: 40px;
object-fit: cover;
}
.c1 .c2:nth-child(1) {
.c1 img:nth-child(1) {
border-radius: 20px 0 0 20px;
object-position: 0 0;
}
.c1 .c2:nth-child(2) {
.c1 img:nth-child(2) {
border-radius: 0 20px 20px 0;
object-position: 100% 0;
}
......@@ -143,6 +137,12 @@ exports[`PortfolioLogo renders without L2 icon 1`] = `
left: 0;
}
.c2 {
width: 40px;
height: 40px;
border-radius: 50%;
}
<div>
<div
class="c0"
......@@ -151,11 +151,11 @@ exports[`PortfolioLogo renders without L2 icon 1`] = `
class="c1"
>
<img
class="c2 c3"
class="c2"
src="https://raw.githubusercontent.com/Uniswap/assets/master/blockchains/ethereum/assets/0x6B175474E89094C44Da98b954EedeAC495271d0F/logo.png"
/>
<img
class="c2 c3"
class="c2"
src="https://raw.githubusercontent.com/Uniswap/assets/master/blockchains/ethereum/assets/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48/logo.png"
/>
</div>
......
import { ChainId } from '@uniswap/sdk-core'
import { getChainInfo } from 'constants/chainInfo'
import useTokenLogoSource from 'hooks/useAssetLogoSource'
import React from 'react'
import styled, { css } from 'styled-components/macro'
import React, { useState } from 'react'
import styled from 'styled-components/macro'
export const MissingImageLogo = styled.div<{ size?: string }>`
--size: ${({ size }) => size};
......@@ -17,17 +17,21 @@ export const MissingImageLogo = styled.div<{ size?: string }>`
width: ${({ size }) => size ?? '24px'};
`
export const LogoImage = styled.img<{ size: string; useBG?: boolean }>`
const LogoImage = styled.img<{ size: string; imgLoaded?: boolean }>`
opacity: ${({ imgLoaded }) => (imgLoaded ? 1 : 0)};
transition: opacity ${({ theme }) => `${theme.transition.duration.medium} ${theme.transition.timing.in}`};
width: ${({ size }) => size};
height: ${({ size }) => size};
border-radius: 50%;
`
${({ useBG }) =>
useBG &&
css`
background: radial-gradient(white 60%, #ffffff00 calc(70% + 1px));
box-shadow: 0 0 1px white;
`}
const LogoImageWrapper = styled.div<{ size: string; imgLoaded?: boolean }>`
width: ${({ size }) => size};
height: ${({ size }) => size};
background: ${({ theme, imgLoaded }) => (imgLoaded ? 'none' : theme.backgroundInteractive)};
transition: background-color ${({ theme }) => `${theme.transition.duration.medium} ${theme.transition.timing.in}`};
box-shadow: 0 0 1px white;
border-radius: 50%;
`
export type AssetLogoBaseProps = {
......@@ -70,18 +74,23 @@ export default function AssetLogo({
style,
hideL2Icon = false,
}: AssetLogoProps) {
const imageProps = {
alt: `${symbol ?? 'token'} logo`,
size,
}
const [src, nextSrc] = useTokenLogoSource(address, chainId, isNative, backupImg)
const L2Icon = getChainInfo(chainId)?.circleLogoUrl
const [imgLoaded, setImgLoaded] = useState(false)
return (
<LogoContainer style={style}>
{src ? (
<LogoImage {...imageProps} src={src} onError={nextSrc} useBG={true} />
<LogoImageWrapper size={size} imgLoaded={imgLoaded}>
<LogoImage
src={src}
alt={`${symbol ?? 'token'} logo`}
size={size}
onLoad={() => void setImgLoaded(true)}
onError={nextSrc}
imgLoaded={imgLoaded}
/>
</LogoImageWrapper>
) : (
<MissingImageLogo size={size}>
{/* use only first 3 characters of Symbol for design reasons */}
......
......@@ -2,15 +2,15 @@
exports[`LoadedRow.tsx renders a row 1`] = `
<DocumentFragment>
.c18 {
.c19 {
color: #40B66B;
}
.c19 {
.c20 {
color: #40B66B;
}
.c17 {
.c18 {
padding-right: 3px;
display: -webkit-box;
display: -webkit-flex;
......@@ -18,12 +18,23 @@ exports[`LoadedRow.tsx renders a row 1`] = `
display: flex;
}
.c8 {
.c9 {
opacity: 0;
-webkit-transition: opacity 250ms ease-in;
transition: opacity 250ms ease-in;
width: 24px;
height: 24px;
border-radius: 50%;
background: radial-gradient(white 60%,#ffffff00 calc(70% + 1px));
}
.c8 {
width: 24px;
height: 24px;
background: #E8ECFB;
-webkit-transition: background-color 250ms ease-in;
transition: background-color 250ms ease-in;
box-shadow: 0 0 1px white;
border-radius: 50%;
}
.c7 {
......@@ -34,7 +45,7 @@ exports[`LoadedRow.tsx renders a row 1`] = `
display: flex;
}
.c9 {
.c10 {
--size: calc(24px / 2);
width: var(--size);
height: var(--size);
......@@ -113,7 +124,7 @@ exports[`LoadedRow.tsx renders a row 1`] = `
font-size: 14px;
}
.c13 {
.c14 {
-webkit-box-pack: end;
-webkit-justify-content: flex-end;
-ms-flex-pack: end;
......@@ -127,7 +138,7 @@ exports[`LoadedRow.tsx renders a row 1`] = `
transition: background-color 250ms ease;
}
.c21 {
.c22 {
padding-right: 8px;
}
......@@ -141,19 +152,19 @@ exports[`LoadedRow.tsx renders a row 1`] = `
gap: 8px;
}
.c14 {
.c15 {
padding-right: 8px;
}
.c20 {
.c21 {
padding-right: 8px;
}
.c16 {
.c17 {
display: none;
}
.c15 {
.c16 {
-webkit-box-pack: end;
-webkit-justify-content: flex-end;
-ms-flex-pack: end;
......@@ -163,12 +174,12 @@ exports[`LoadedRow.tsx renders a row 1`] = `
flex: 1;
}
.c23 {
.c24 {
padding: 0px 24px;
min-width: 120px;
}
.c24 {
.c25 {
width: 124px;
height: 42px;
}
......@@ -178,7 +189,7 @@ exports[`LoadedRow.tsx renders a row 1`] = `
text-decoration: none;
}
.c10 {
.c11 {
gap: 8px;
line-height: 24px;
font-size: 16px;
......@@ -188,19 +199,19 @@ exports[`LoadedRow.tsx renders a row 1`] = `
white-space: nowrap;
}
.c11 {
.c12 {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
max-width: 100%;
}
.c12 {
.c13 {
color: #98A1C0;
text-transform: uppercase;
}
.c22 {
.c23 {
padding-right: 8px;
}
......@@ -241,19 +252,19 @@ exports[`LoadedRow.tsx renders a row 1`] = `
}
@media only screen and (max-width:720px) {
.c21 {
.c22 {
display: none;
}
}
@media only screen and (max-width:540px) {
.c20 {
.c21 {
display: none;
}
}
@media only screen and (max-width:540px) {
.c16 {
.c17 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
......@@ -269,7 +280,7 @@ exports[`LoadedRow.tsx renders a row 1`] = `
}
@media only screen and (max-width:540px) {
.c15 {
.c16 {
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
......@@ -281,13 +292,13 @@ exports[`LoadedRow.tsx renders a row 1`] = `
}
@media only screen and (max-width:1200px) {
.c23 {
.c24 {
display: none;
}
}
@media only screen and (max-width:540px) {
.c10 {
.c11 {
-webkit-box-pack: start;
-webkit-justify-content: flex-start;
-ms-flex-pack: start;
......@@ -304,7 +315,7 @@ exports[`LoadedRow.tsx renders a row 1`] = `
}
@media only screen and (max-width:540px) {
.c12 {
.c13 {
font-size: 12px;
height: 16px;
-webkit-box-pack: start;
......@@ -316,7 +327,7 @@ exports[`LoadedRow.tsx renders a row 1`] = `
}
@media only screen and (max-width:840px) {
.c22 {
.c23 {
display: none;
}
}
......@@ -346,26 +357,30 @@ exports[`LoadedRow.tsx renders a row 1`] = `
<div
class="c7"
>
<img
alt="USDC logo"
<div
class="c8"
src="https://raw.githubusercontent.com/Uniswap/assets/master/blockchains/ethereum/assets/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48/logo.png"
/>
>
<img
alt="USDC logo"
class="c9"
src="https://raw.githubusercontent.com/Uniswap/assets/master/blockchains/ethereum/assets/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48/logo.png"
/>
</div>
<div
class="c9"
class="c10"
/>
</div>
<div
class="7 c2 c10"
class="7 c2 c11"
>
<div
class="8 c11"
class="8 c12"
data-cy="token-name"
>
USD Coin
</div>
<div
class="9 c2 c12"
class="9 c2 c13"
>
USDC
</div>
......@@ -373,25 +388,25 @@ exports[`LoadedRow.tsx renders a row 1`] = `
</div>
</div>
<div
class="c2 c13 c14"
class="c2 c14 c15"
data-testid="price-cell"
>
<div
class="c5"
>
<div
class="2 c2 c15"
class="2 c2 c16"
>
$1.00
<div
class="1 c2 c16"
class="1 c2 c17"
>
<div
class="c17"
class="c18"
>
<svg
aria-label="up"
class="c18"
class="c19"
fill="none"
height="14"
stroke="currentColor"
......@@ -414,7 +429,7 @@ exports[`LoadedRow.tsx renders a row 1`] = `
</svg>
</div>
<span
class="c19"
class="c20"
>
0.00%
</span>
......@@ -423,18 +438,18 @@ exports[`LoadedRow.tsx renders a row 1`] = `
</div>
</div>
<div
class="0 c2 c13 c20"
class="0 c2 c14 c21"
data-testid="percent-change-cell"
>
<div
class="c5"
>
<div
class="c17"
class="c18"
>
<svg
aria-label="up"
class="c18"
class="c19"
fill="none"
height="20"
stroke="currentColor"
......@@ -457,14 +472,14 @@ exports[`LoadedRow.tsx renders a row 1`] = `
</svg>
</div>
<span
class="c19"
class="c20"
>
0.00%
</span>
</div>
</div>
<div
class="c2 c13 c21"
class="c2 c14 c22"
data-testid="tvl-cell"
>
<div
......@@ -474,7 +489,7 @@ exports[`LoadedRow.tsx renders a row 1`] = `
</div>
</div>
<div
class="0 c2 c13 c22"
class="0 c2 c14 c23"
data-testid="volume-cell"
>
<div
......@@ -484,10 +499,10 @@ exports[`LoadedRow.tsx renders a row 1`] = `
</div>
</div>
<div
class="4 c2 c23"
class="4 c2 c24"
>
<div
class="5 c2 c24"
class="5 c2 c25"
>
<div
style="width: 100%; height: 100%;"
......
......@@ -34,7 +34,7 @@ exports[`SwapModalHeader.tsx matches base snapshot, test trade exact input 1`] =
color: #0D111C;
}
.c12 {
.c13 {
width: 100%;
height: 1px;
border-width: 0;
......@@ -78,12 +78,23 @@ exports[`SwapModalHeader.tsx matches base snapshot, test trade exact input 1`] =
grid-row-gap: 8px;
}
.c11 {
.c12 {
opacity: 0;
-webkit-transition: opacity 250ms ease-in;
transition: opacity 250ms ease-in;
width: 36px;
height: 36px;
border-radius: 50%;
background: radial-gradient(white 60%,#ffffff00 calc(70% + 1px));
}
.c11 {
width: 36px;
height: 36px;
background: #E8ECFB;
-webkit-transition: background-color 250ms ease-in;
transition: background-color 250ms ease-in;
box-shadow: 0 0 1px white;
border-radius: 50%;
}
.c10 {
......@@ -105,7 +116,7 @@ exports[`SwapModalHeader.tsx matches base snapshot, test trade exact input 1`] =
margin-right: 8px;
}
.c13 {
.c14 {
margin: 16px 2px 24px 2px;
}
......@@ -155,11 +166,15 @@ exports[`SwapModalHeader.tsx matches base snapshot, test trade exact input 1`] =
<div
class="c10"
>
<img
alt="ABC logo"
<div
class="c11"
src="https://raw.githubusercontent.com/Uniswap/assets/master/blockchains/ethereum/assets/0x0000000000000000000000000000000000000001/logo.png"
/>
>
<img
alt="ABC logo"
class="c12"
src="https://raw.githubusercontent.com/Uniswap/assets/master/blockchains/ethereum/assets/0x0000000000000000000000000000000000000001/logo.png"
/>
</div>
</div>
</div>
<div
......@@ -198,16 +213,20 @@ exports[`SwapModalHeader.tsx matches base snapshot, test trade exact input 1`] =
<div
class="c10"
>
<img
alt="DEF logo"
<div
class="c11"
src="https://raw.githubusercontent.com/Uniswap/assets/master/blockchains/ethereum/assets/0x0000000000000000000000000000000000000002/logo.png"
/>
>
<img
alt="DEF logo"
class="c12"
src="https://raw.githubusercontent.com/Uniswap/assets/master/blockchains/ethereum/assets/0x0000000000000000000000000000000000000002/logo.png"
/>
</div>
</div>
</div>
</div>
<div
class="c12 c13"
class="c13 c14"
/>
</div>
</DocumentFragment>
......@@ -247,7 +266,7 @@ exports[`SwapModalHeader.tsx renders ETH input token for an ETH input UniswapX s
color: #0D111C;
}
.c12 {
.c13 {
width: 100%;
height: 1px;
border-width: 0;
......@@ -291,12 +310,23 @@ exports[`SwapModalHeader.tsx renders ETH input token for an ETH input UniswapX s
grid-row-gap: 8px;
}
.c11 {
.c12 {
opacity: 0;
-webkit-transition: opacity 250ms ease-in;
transition: opacity 250ms ease-in;
width: 36px;
height: 36px;
border-radius: 50%;
background: radial-gradient(white 60%,#ffffff00 calc(70% + 1px));
}
.c11 {
width: 36px;
height: 36px;
background: #E8ECFB;
-webkit-transition: background-color 250ms ease-in;
transition: background-color 250ms ease-in;
box-shadow: 0 0 1px white;
border-radius: 50%;
}
.c10 {
......@@ -318,7 +348,7 @@ exports[`SwapModalHeader.tsx renders ETH input token for an ETH input UniswapX s
margin-right: 8px;
}
.c13 {
.c14 {
margin: 16px 2px 24px 2px;
}
......@@ -368,11 +398,15 @@ exports[`SwapModalHeader.tsx renders ETH input token for an ETH input UniswapX s
<div
class="c10"
>
<img
alt="ETH logo"
<div
class="c11"
src="ethereum-logo.png"
/>
>
<img
alt="ETH logo"
class="c12"
src="ethereum-logo.png"
/>
</div>
</div>
</div>
<div
......@@ -411,16 +445,20 @@ exports[`SwapModalHeader.tsx renders ETH input token for an ETH input UniswapX s
<div
class="c10"
>
<img
alt="DEF logo"
<div
class="c11"
src="https://raw.githubusercontent.com/Uniswap/assets/master/blockchains/ethereum/assets/0x0000000000000000000000000000000000000002/logo.png"
/>
>
<img
alt="DEF logo"
class="c12"
src="https://raw.githubusercontent.com/Uniswap/assets/master/blockchains/ethereum/assets/0x0000000000000000000000000000000000000002/logo.png"
/>
</div>
</div>
</div>
</div>
<div
class="c12 c13"
class="c13 c14"
/>
</div>
</DocumentFragment>
......@@ -460,7 +498,7 @@ exports[`SwapModalHeader.tsx test trade exact output, no recipient 1`] = `
color: #0D111C;
}
.c12 {
.c13 {
width: 100%;
height: 1px;
border-width: 0;
......@@ -504,12 +542,23 @@ exports[`SwapModalHeader.tsx test trade exact output, no recipient 1`] = `
grid-row-gap: 8px;
}
.c11 {
.c12 {
opacity: 0;
-webkit-transition: opacity 250ms ease-in;
transition: opacity 250ms ease-in;
width: 36px;
height: 36px;
border-radius: 50%;
background: radial-gradient(white 60%,#ffffff00 calc(70% + 1px));
}
.c11 {
width: 36px;
height: 36px;
background: #E8ECFB;
-webkit-transition: background-color 250ms ease-in;
transition: background-color 250ms ease-in;
box-shadow: 0 0 1px white;
border-radius: 50%;
}
.c10 {
......@@ -531,7 +580,7 @@ exports[`SwapModalHeader.tsx test trade exact output, no recipient 1`] = `
margin-right: 8px;
}
.c13 {
.c14 {
margin: 16px 2px 24px 2px;
}
......@@ -581,11 +630,15 @@ exports[`SwapModalHeader.tsx test trade exact output, no recipient 1`] = `
<div
class="c10"
>
<img
alt="ABC logo"
<div
class="c11"
src="https://raw.githubusercontent.com/Uniswap/assets/master/blockchains/ethereum/assets/0x0000000000000000000000000000000000000001/logo.png"
/>
>
<img
alt="ABC logo"
class="c12"
src="https://raw.githubusercontent.com/Uniswap/assets/master/blockchains/ethereum/assets/0x0000000000000000000000000000000000000001/logo.png"
/>
</div>
</div>
</div>
<div
......@@ -624,16 +677,20 @@ exports[`SwapModalHeader.tsx test trade exact output, no recipient 1`] = `
<div
class="c10"
>
<img
alt="GHI logo"
<div
class="c11"
src="https://raw.githubusercontent.com/Uniswap/assets/master/blockchains/ethereum/assets/0x0000000000000000000000000000000000000003/logo.png"
/>
>
<img
alt="GHI logo"
class="c12"
src="https://raw.githubusercontent.com/Uniswap/assets/master/blockchains/ethereum/assets/0x0000000000000000000000000000000000000003/logo.png"
/>
</div>
</div>
</div>
</div>
<div
class="c12 c13"
class="c13 c14"
/>
</div>
</DocumentFragment>
......
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