From 667350d15a6ca00910831c6e90097f2dc0b06946 Mon Sep 17 00:00:00 2001 From: Ariella Vu Date: Tue, 25 Jan 2022 20:16:56 +0000 Subject: [PATCH] Convert ConfirmAddSuggestedToken to a functional component + cleanup (#13377) * FC: ConfirmAddSuggestedToken - change class to functional component * clean: reorganize functions (no logic change) * FC: ConfirmAddSuggestedToken pt. 2 - preserve trackEvent logic -> metricsEvent * clean: rm _ prefix from fn name - why? now, only 3 other functions remain prefixed w/ '_' * clean: update useEffect hook * clean: alphabetize props * clean: functions in ConfirmAddSuggestedToken * clean: use arrow fn for FC --- .../confirm-add-suggested-token.component.js | 323 ++++++++---------- 1 file changed, 148 insertions(+), 175 deletions(-) diff --git a/ui/pages/confirm-add-suggested-token/confirm-add-suggested-token.component.js b/ui/pages/confirm-add-suggested-token/confirm-add-suggested-token.component.js index fdb3a84ab..60656b753 100644 --- a/ui/pages/confirm-add-suggested-token/confirm-add-suggested-token.component.js +++ b/ui/pages/confirm-add-suggested-token/confirm-add-suggested-token.component.js @@ -1,192 +1,49 @@ -import React, { Component } from 'react'; +import React, { useContext, useEffect } from 'react'; import PropTypes from 'prop-types'; import Button from '../../components/ui/button'; import Identicon from '../../components/ui/identicon'; import TokenBalance from '../../components/ui/token-balance'; +import { I18nContext } from '../../contexts/i18n'; +import { MetaMetricsContext } from '../../contexts/metametrics'; import { isEqualCaseInsensitive } from '../../helpers/utils/util'; -export default class ConfirmAddSuggestedToken extends Component { - static contextTypes = { - t: PropTypes.func, - trackEvent: PropTypes.func, - }; +function getTokenName(name, symbol) { + return typeof name === 'undefined' ? symbol : `${name} (${symbol})`; +} +const ConfirmAddSuggestedToken = (props) => { + const { + acceptWatchAsset, + history, + mostRecentOverviewPage, + rejectWatchAsset, + suggestedAssets, + tokens, + } = props; - static propTypes = { - history: PropTypes.object, - acceptWatchAsset: PropTypes.func, - rejectWatchAsset: PropTypes.func, - mostRecentOverviewPage: PropTypes.string.isRequired, - suggestedAssets: PropTypes.array, - tokens: PropTypes.array, - }; + const metricsEvent = useContext(MetaMetricsContext); + const t = useContext(I18nContext); - componentDidMount() { - this._checksuggestedAssets(); - } - - componentDidUpdate() { - this._checksuggestedAssets(); - } - - _checksuggestedAssets() { - const { - mostRecentOverviewPage, - suggestedAssets = [], - history, - } = this.props; - - if (suggestedAssets.length > 0) { - return; - } - - history.push(mostRecentOverviewPage); - } - - getTokenName(name, symbol) { - return typeof name === 'undefined' ? symbol : `${name} (${symbol})`; - } - - render() { - const { - suggestedAssets, - tokens, - rejectWatchAsset, - history, - mostRecentOverviewPage, - acceptWatchAsset, - } = this.props; - - const hasTokenDuplicates = this.checkTokenDuplicates( - suggestedAssets, - tokens, - ); - const reusesName = this.checkNameReuse(suggestedAssets, tokens); - - return ( -
-
-
- {this.context.t('addSuggestedTokens')} -
-
- {this.context.t('likeToImportTokens')} -
- {hasTokenDuplicates ? ( -
{this.context.t('knownTokenWarning')}
- ) : null} - {reusesName ? ( -
- {this.context.t('reusedTokenNameWarning')} -
- ) : null} -
-
-
-
-
- {this.context.t('token')} -
-
- {this.context.t('balance')} -
-
-
- {suggestedAssets.map(({ asset }) => { - return ( -
-
- -
- {this.getTokenName(asset.name, asset.symbol)} -
-
-
- -
-
- ); - })} -
-
-
-
-
- - -
-
-
- ); - } - - checkTokenDuplicates(suggestedAssets, tokens) { - const pending = suggestedAssets.map(({ asset }) => - asset.address.toUpperCase(), - ); - const existing = tokens.map((token) => token.address.toUpperCase()); - const dupes = pending.filter((proposed) => { - return existing.includes(proposed); + const tokenAddedEvent = (asset) => { + metricsEvent({ + event: 'Token Added', + category: 'Wallet', + sensitiveProperties: { + token_symbol: asset.symbol, + token_contract_address: asset.address, + token_decimal_precision: asset.decimals, + unlisted: asset.unlisted, + source: 'dapp', + }, }); - - return dupes.length > 0; - } + }; /** * Returns true if any suggestedAssets both: * - Share a symbol with an existing `tokens` member. * - Does not share an address with that same `tokens` member. * This should be flagged as possibly deceptive or confusing. - * - * @param suggestedAssets - * @param tokens */ - checkNameReuse(suggestedAssets, tokens) { + const checkNameReuse = () => { const duplicates = suggestedAssets.filter(({ asset }) => { const dupes = tokens.filter( (old) => @@ -196,5 +53,121 @@ export default class ConfirmAddSuggestedToken extends Component { return dupes.length > 0; }); return duplicates.length > 0; - } -} + }; + + const checkTokenDuplicates = () => { + const pending = suggestedAssets.map(({ asset }) => + asset.address.toUpperCase(), + ); + const existing = tokens.map((token) => token.address.toUpperCase()); + const dupes = pending.filter((proposed) => { + return existing.includes(proposed); + }); + + return dupes.length > 0; + }; + + const hasTokenDuplicates = checkTokenDuplicates(); + const reusesName = checkNameReuse(); + + useEffect(() => { + if (!suggestedAssets.length) { + history.push(mostRecentOverviewPage); + } + }, [history, suggestedAssets, mostRecentOverviewPage]); + + return ( +
+
+
{t('addSuggestedTokens')}
+
+ {t('likeToImportTokens')} +
+ {hasTokenDuplicates ? ( +
{t('knownTokenWarning')}
+ ) : null} + {reusesName ? ( +
{t('reusedTokenNameWarning')}
+ ) : null} +
+
+
+
+
{t('token')}
+
{t('balance')}
+
+
+ {suggestedAssets.map(({ asset }) => { + return ( +
+
+ +
+ {getTokenName(asset.name, asset.symbol)} +
+
+
+ +
+
+ ); + })} +
+
+
+
+ +
+
+ ); +}; + +ConfirmAddSuggestedToken.propTypes = { + acceptWatchAsset: PropTypes.func, + history: PropTypes.object, + mostRecentOverviewPage: PropTypes.string.isRequired, + rejectWatchAsset: PropTypes.func, + suggestedAssets: PropTypes.array, + tokens: PropTypes.array, +}; + +export default ConfirmAddSuggestedToken;