import React, { Component } from 'react'; import PropTypes from 'prop-types'; import SendRowWrapper from '../send-row-wrapper'; import Identicon from '../../../../components/ui/identicon'; import TokenBalance from '../../../../components/ui/token-balance'; import TokenListDisplay from '../../../../components/app/token-list-display'; import UserPreferencedCurrencyDisplay from '../../../../components/app/user-preferenced-currency-display'; import { PRIMARY } from '../../../../helpers/constants/common'; import { isEqualCaseInsensitive } from '../../../../../shared/modules/string-utils'; import { EVENT } from '../../../../../shared/constants/metametrics'; import { AssetType, TokenStandard, } from '../../../../../shared/constants/transaction'; export default class SendAssetRow extends Component { static propTypes = { tokens: PropTypes.arrayOf( PropTypes.shape({ address: PropTypes.string, decimals: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), symbol: PropTypes.string, image: PropTypes.string, }), ).isRequired, accounts: PropTypes.object.isRequired, selectedAddress: PropTypes.string.isRequired, sendAsset: PropTypes.object, updateSendAsset: PropTypes.func.isRequired, nativeCurrency: PropTypes.string, nativeCurrencyImage: PropTypes.string, collectibles: PropTypes.arrayOf( PropTypes.shape({ address: PropTypes.string.isRequired, tokenId: PropTypes.string.isRequired, name: PropTypes.string, description: PropTypes.string, image: PropTypes.string, standard: PropTypes.string, imageThumbnail: PropTypes.string, imagePreview: PropTypes.string, creator: PropTypes.shape({ address: PropTypes.string, config: PropTypes.string, profile_img_url: PropTypes.string, }), }), ), collections: PropTypes.arrayOf( PropTypes.shape({ address: PropTypes.string.isRequired, name: PropTypes.string, }), ), }; static contextTypes = { t: PropTypes.func, trackEvent: PropTypes.func, }; state = { isShowingDropdown: false, sendableTokens: [], sendableCollectibles: [], }; async componentDidMount() { const sendableTokens = this.props.tokens.filter((token) => !token.isERC721); const sendableCollectibles = this.props.collectibles.filter( (collectible) => collectible.isCurrentlyOwned && collectible.standard === TokenStandard.ERC721, ); this.setState({ sendableTokens, sendableCollectibles }); } openDropdown = () => this.setState({ isShowingDropdown: true }); closeDropdown = () => this.setState({ isShowingDropdown: false }); getAssetSelected = (type, token) => { switch (type) { case AssetType.native: return this.props.nativeCurrency; case AssetType.token: return TokenStandard.ERC20; case AssetType.NFT: return token?.standard; default: return null; } }; selectToken = (type, token) => { this.setState( { isShowingDropdown: false, }, () => { this.context.trackEvent({ category: EVENT.CATEGORIES.TRANSACTIONS, event: 'User clicks "Assets" dropdown', properties: { action: 'Send Screen', legacy_event: true, assetSelected: this.getAssetSelected(type, token), }, }); this.props.updateSendAsset({ type, details: type === AssetType.native ? null : token, }); }, ); }; render() { const { t } = this.context; return (
{this.renderSendAsset()}
{[...this.state.sendableTokens, ...this.state.sendableCollectibles] .length > 0 ? this.renderAssetDropdown() : null}
); } renderSendAsset() { const { sendAsset: { details, type }, tokens, collectibles, } = this.props; if (type === AssetType.token) { const token = tokens.find(({ address }) => isEqualCaseInsensitive(address, details.address), ); if (token) { return this.renderToken(token); } } else if (type === AssetType.NFT) { const collectible = collectibles.find( ({ address, tokenId }) => isEqualCaseInsensitive(address, details.address) && tokenId === details.tokenId, ); if (collectible) { return this.renderCollectible(collectible); } } return this.renderNativeCurrency(); } renderAssetDropdown() { return ( this.state.isShowingDropdown && (
{this.renderNativeCurrency(true)} this.selectToken(AssetType.token, token)} /> {this.state.sendableCollectibles.map((collectible) => this.renderCollectible(collectible, true), )}
) ); } renderNativeCurrency(insideDropdown = false) { const { t } = this.context; const { accounts, selectedAddress, nativeCurrency, nativeCurrencyImage } = this.props; const { sendableTokens, sendableCollectibles } = this.state; const balanceValue = accounts[selectedAddress] ? accounts[selectedAddress].balance : ''; const sendableAssets = [...sendableTokens, ...sendableCollectibles]; return (
0 ? 'send-v2__asset-dropdown__asset' : 'send-v2__asset-dropdown__single-asset' } onClick={() => this.selectToken(AssetType.native)} >
{nativeCurrency}
{`${t('balance')}:`}
{!insideDropdown && sendableAssets.length > 0 && ( )}
); } renderToken(token, insideDropdown = false) { const { address, symbol, image } = token; const { t } = this.context; return (
this.selectToken(AssetType.token, token)} >
{symbol}
{`${t('balance')}:`}
{!insideDropdown && ( )}
); } renderCollectible(collectible, insideDropdown = false) { const { address, name, image, tokenId } = collectible; const { t } = this.context; const collectibleCollection = this.props.collections.find( (collection) => collection.address === address, ); return (
this.selectToken(AssetType.NFT, collectible)} >
{collectibleCollection.name || name}
{`${t('tokenId')}:`} {tokenId}
{!insideDropdown && ( )}
); } }