Skip to content

Commit

Permalink
feat(wallet): Network Identifications in Portfolio
Browse files Browse the repository at this point in the history
  • Loading branch information
Douglashdaniel committed Feb 8, 2022
1 parent ce05c1f commit 80ece88
Show file tree
Hide file tree
Showing 12 changed files with 182 additions and 26 deletions.
2 changes: 2 additions & 0 deletions components/brave_wallet/browser/brave_wallet_constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ constexpr webui::LocalizedString kLocalizedStrings[] = {
{"braveWalletChartAllTime", IDS_BRAVE_WALLET_CHART_ALL_TIME},
{"braveWalletAddCoin", IDS_BRAVE_WALLET_ADD_COIN},
{"braveWalletBalance", IDS_BRAVE_WALLET_BALANCE},
{"braveWalletPortfolioAssetNetworkDescription",
IDS_BRAVE_WALLET_PORTFOLIO_ASSET_NETWORK_DESCRIPTION},
{"braveWalletAccounts", IDS_BRAVE_WALLET_ACCOUNTS},
{"braveWalletAccount", IDS_BRAVE_WALLET_ACCOUNT},
{"braveWalletOwner", IDS_BRAVE_WALLET_OWNER},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
formatFiatAmountWithCommasAndDecimals,
formatTokenAmountWithCommasAndDecimals
} from '../../../utils/format-prices'
import { getLocale } from '../../../../common/locale'

// Styled Components
import {
Expand All @@ -18,9 +19,12 @@ import {
BalanceColumn,
FiatBalanceText,
NameAndIcon,
AssetIcon
AssetIcon,
IconsWrapper,
NetworkIconWrapper,
NameColumn
} from './style'
import { withPlaceholderIcon } from '../../shared'
import { withPlaceholderIcon, CreateNetworkIcon } from '../../shared'
import { WithHideBalancePlaceholder } from '../'

// Hooks
Expand All @@ -33,6 +37,7 @@ interface Props {
token: BraveWallet.BlockchainToken
defaultCurrencies: DefaultCurrencies
hideBalances?: boolean
selectedNetwork?: BraveWallet.EthereumChain
}

const PortfolioAssetItem = (props: Props) => {
Expand All @@ -42,7 +47,8 @@ const PortfolioAssetItem = (props: Props) => {
action,
token,
defaultCurrencies,
hideBalances
hideBalances,
selectedNetwork
} = props

const AssetIconWithPlaceholder = React.useMemo(() => {
Expand All @@ -58,14 +64,33 @@ const PortfolioAssetItem = (props: Props) => {
return computeFiatAmount(assetBalance, token.symbol, token.decimals)
}, [computeFiatAmount, assetBalance, token])

const NetworkDescription = React.useMemo(() => {
if (selectedNetwork && token.contractAddress !== '') {
return getLocale('braveWalletPortfolioAssetNetworkDescription')
.replace('$1', token.symbol)
.replace('$2', selectedNetwork?.chainName ?? '')
}
return token.symbol
}, [selectedNetwork, token])

return (
<>
{token.visible &&
// Selecting an erc721 token is temp disabled until UI is ready for viewing NFT's
<StyledWrapper disabled={token.isErc721} onClick={action}>
<NameAndIcon>
<AssetIconWithPlaceholder selectedAsset={token} />
<AssetName>{token.name} {token.isErc721 ? hexToNumber(token.tokenId ?? '') : ''}</AssetName>
<IconsWrapper>
<AssetIconWithPlaceholder selectedAsset={token} />
{selectedNetwork && token.contractAddress !== '' &&
<NetworkIconWrapper>
<CreateNetworkIcon network={selectedNetwork} marginRight={0} />
</NetworkIconWrapper>
}
</IconsWrapper>
<NameColumn>
<AssetName>{token.name} {token.isErc721 ? hexToNumber(token.tokenId ?? '') : ''}</AssetName>
<AssetName>{NetworkDescription}</AssetName>
</NameColumn>
</NameAndIcon>
<BalanceColumn>
<WithHideBalancePlaceholder
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,32 @@ export const AssetIcon = AssetIconFactory<AssetIconProps>({
width: '40px',
height: 'auto'
})

export const IconsWrapper = styled.div`
display: flex;
align-items: center;
justify-content: center;
flex-direction: row;
position: relative;
margin-right: 6px;
`

export const NetworkIconWrapper = styled.div`
display: flex;
align-items: center;
justify-content: center;
flex-direction: row;
position: absolute;
bottom: 0px;
right: 4px;
background-color: ${(p) => p.theme.color.background02};
border-radius: 100%;
padding: 2px;
`

export const NameColumn = styled.div`
display: flex;
align-items: flex-start;
justify-content: center;
flex-direction: column;
`
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export interface Props {
defaultCurrencies: DefaultCurrencies
userAssetList: UserAssetInfoType[]
hideBalances: boolean
selectedNetwork: BraveWallet.EthereumChain
onSetFilteredAssetList: (filteredList: UserAssetInfoType[]) => void
onSelectAsset: (asset: BraveWallet.BlockchainToken | undefined) => () => void
onShowAssetModal: () => void
Expand All @@ -43,6 +44,7 @@ const TokenLists = (props: Props) => {
defaultCurrencies,
userAssetList,
hideBalances,
selectedNetwork,
onSelectAsset,
onShowAssetModal,
onSetFilteredAssetList
Expand Down Expand Up @@ -80,6 +82,7 @@ const TokenLists = (props: Props) => {
assetBalance={item.assetBalance}
token={item.asset}
hideBalances={hideBalances}
selectedNetwork={selectedNetwork}
/>
)}
{erc721TokenList.length !== 0 &&
Expand All @@ -96,6 +99,7 @@ const TokenLists = (props: Props) => {
assetBalance={item.assetBalance}
token={item.asset}
hideBalances={hideBalances}
selectedNetwork={selectedNetwork}
/>
)}
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,7 @@ const Portfolio = (props: Props) => {
userAssetList={userAssetList}
filteredAssetList={filteredAssetList}
tokenPrices={transactionSpotPrices}
selectedNetwork={selectedNetwork}
onSetFilteredAssetList={onSetFilteredAssetList}
onSelectAsset={selectAsset}
onShowAssetModal={toggleShowVisibleAssetModal}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import * as React from 'react'
import { BraveWallet } from '../../../constants/types'
import { IconWrapper, Placeholder, NetworkIcon } from './style'
import { stripERC20TokenImageURL, isRemoteImageURL, isValidIconExtension } from '../../../utils/string-utils'
import { create } from 'ethereum-blockies'
import {
ETHIconUrl
} from '../../../assets/asset-icons'

interface Props {
network: BraveWallet.EthereumChain
marginRight: number
}

function CreateNetworkIcon (props: Props) {
const { network, marginRight } = props
if (!network) {
return null
}
const networkImageURL = stripERC20TokenImageURL(network?.iconUrls[0])
const isRemoteURL = isRemoteImageURL(networkImageURL)
const isDataURL = network.iconUrls[0]?.startsWith('chrome://erc-token-images/')
const isStorybook = network.iconUrls[0]?.startsWith('static/media/components/brave_wallet_ui/')

const isValidIcon = React.useMemo(() => {
if (isRemoteURL || isDataURL) {
const url = new URL(network.iconUrls[0])
return isValidIconExtension(url.pathname)
}
if (isStorybook) {
return true
}
return false
}, [isRemoteURL, isDataURL, networkImageURL])

// Will remove these hardcoded chainId's.
// We need to return a normal Ethereum Icon URL for Ethereum Mainnet
// and return a grayed out Ethereum Icon Url for Ethereum Test Networks from the backend.
const testNetworkList = ['0x4', '0x3', '0x5', '0x2a', '0x539']
const needsPlaceholder = !['0x1', ...testNetworkList].includes(network.chainId) && (networkImageURL === '' || !isValidIcon)

const orb = React.useMemo(() => {
if (needsPlaceholder) {
return create({ seed: network.chainName, size: 8, scale: 16 }).toDataURL()
}
}, [network])

const remoteImage = React.useMemo(() => {
if (isRemoteURL) {
return `chrome://image?${networkImageURL}`
}
return ''
}, [networkImageURL])

if (needsPlaceholder) {
return (
<IconWrapper
marginRight={marginRight ?? 0}
isTestnet={false}
>
<Placeholder
orb={orb}
/>
</IconWrapper>
)
}
return (
<IconWrapper
marginRight={marginRight ?? 0}
isTestnet={testNetworkList.includes(network.chainId)}
>
<NetworkIcon icon={['0x1', ...testNetworkList].includes(network.chainId) ? ETHIconUrl : isRemoteURL ? remoteImage : network.iconUrls[0]} />
</IconWrapper>
)
}

export default CreateNetworkIcon
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import styled from 'styled-components'
import { AssetIconFactory, AssetIconProps } from '../style'

interface StyleProps {
marginRight: number
isTestnet: boolean
orb: string
}

export const IconWrapper = styled.div<Partial<StyleProps>>`
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
width: 15px;
height: 15px;
margin-right: ${(p) => `${p.marginRight}px`};
filter: ${(p) => p.isTestnet ? 'grayscale(100%)' : 'none'};
`

export const Placeholder = styled.div<Partial<StyleProps>>`
width: 10px;
height: 10px;
border-radius: 100%;
background-image: url(${(p) => p.orb});
background-size: cover;
`

export const NetworkIcon = AssetIconFactory<AssetIconProps>({
width: '15px',
height: 'auto'
})
4 changes: 3 additions & 1 deletion components/brave_wallet_ui/components/shared/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import Tooltip from './tooltip'
import SelectNetwork from './select-network'
import SelectAccount from './select-account'
import withPlaceholderIcon from './create-placeholder-icon'
import CreateNetworkIcon from './create-network-icon'

export {
AppListItem,
Expand All @@ -17,5 +18,6 @@ export {
Tooltip,
SelectNetwork,
SelectAccount,
withPlaceholderIcon
withPlaceholderIcon,
CreateNetworkIcon
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import * as React from 'react'
import { BraveWallet } from '../../../constants/types'
import { create } from 'ethereum-blockies'
import { CreateNetworkIcon } from '../'
// Styled Components
import {
StyledWrapper,
AccountCircle,
NetworkName,
LeftSide,
BigCheckMark
Expand All @@ -19,14 +18,10 @@ export interface Props {
function SelectNetworkItem (props: Props) {
const { network, onSelectNetwork, selectedNetwork } = props

const orb = React.useMemo(() => {
return create({ seed: network.chainName, size: 8, scale: 16 }).toDataURL()
}, [network])

return (
<StyledWrapper onClick={onSelectNetwork}>
<LeftSide>
<AccountCircle orb={orb} />
<CreateNetworkIcon network={network} marginRight={14} />
<NetworkName>{network.chainName}</NetworkName>
</LeftSide>
{selectedNetwork.chainId === network.chainId &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@ import styled from 'styled-components'
import { WalletButton } from '../style'
import CheckMark from '../../../assets/svg-icons/big-checkmark.svg'

interface StyleProps {
orb: string
}

export const StyledWrapper = styled(WalletButton)`
display: flex;
width: 100%;
Expand Down Expand Up @@ -38,15 +34,6 @@ export const NetworkName = styled.span`
text-align: left;
`

export const AccountCircle = styled.div<StyleProps>`
width: 10px;
height: 10px;
border-radius: 100%;
background-image: url(${(p) => p.orb});
background-size: cover;
margin-right: 14px;
`

export const BigCheckMark = styled.div`
width: 14px;
height: 14px;
Expand Down
1 change: 1 addition & 0 deletions components/brave_wallet_ui/stories/locale.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ provideStrings({
// Portfolio View
braveWalletAddCoin: 'Add Coin',
braveWalletBalance: 'Balance',
braveWalletPortfolioAssetNetworkDescription: '$1 on $2',

// Portfolio SubView
braveWalletAccounts: 'Accounts',
Expand Down
1 change: 1 addition & 0 deletions components/resources/wallet_strings.grdp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
<message name="IDS_BRAVE_WALLET_CHART_ALL_TIME" desc="Chart control bar All button">All</message>
<message name="IDS_BRAVE_WALLET_ADD_COIN" desc="Portfolio Add Coin button">Add Coin</message>
<message name="IDS_BRAVE_WALLET_BALANCE" desc="Portfolio Balance title">Balance</message>
<message name="IDS_BRAVE_WALLET_PORTFOLIO_ASSET_NETWORK_DESCRIPTION" desc="Portfolio Asset Item Network Description"><ph name="SYMBOL"><ex>BAT</ex>$1</ph> on <ph name="NETWORK"><ex>Ethereum Mainnet</ex>$2</ph></message>
<message name="IDS_BRAVE_WALLET_ACCOUNTS" desc="Accounts subview button">Accounts</message>
<message name="IDS_BRAVE_WALLET_ACCOUNT" desc="Account subview title">Account</message>
<message name="IDS_BRAVE_WALLET_OWNER" desc="Account subview NFT title">Owner</message>
Expand Down

0 comments on commit 80ece88

Please sign in to comment.