diff options
author | Alexander Tseung <alextsg@users.noreply.github.com> | 2018-10-17 07:03:29 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-10-17 07:03:29 +0800 |
commit | badebe017fe28b58ac742082368484c3a4b1c1bc (patch) | |
tree | b0810d259ea104a11051dd48dc1038a9c2d82310 /ui/app/components/pages | |
parent | 8bccb88132447882f81105a0033a4f199200714f (diff) | |
download | tangerine-wallet-browser-badebe017fe28b58ac742082368484c3a4b1c1bc.tar tangerine-wallet-browser-badebe017fe28b58ac742082368484c3a4b1c1bc.tar.gz tangerine-wallet-browser-badebe017fe28b58ac742082368484c3a4b1c1bc.tar.bz2 tangerine-wallet-browser-badebe017fe28b58ac742082368484c3a4b1c1bc.tar.lz tangerine-wallet-browser-badebe017fe28b58ac742082368484c3a4b1c1bc.tar.xz tangerine-wallet-browser-badebe017fe28b58ac742082368484c3a4b1c1bc.tar.zst tangerine-wallet-browser-badebe017fe28b58ac742082368484c3a4b1c1bc.zip |
Adds toggle for primary currency (#5421)
* Add UnitInput component
* Add CurrencyInput component
* Add UserPreferencedCurrencyInput component
* Add UserPreferencedCurrencyDisplay component
* Add updatePreferences action
* Add styles for CurrencyInput, CurrencyDisplay, and UnitInput
* Update SettingsTab page with Primary Currency toggle
* Refactor currency displays and inputs to use UserPreferenced displays and inputs
* Add TokenInput component
* Add UserPreferencedTokenInput component
* Use TokenInput in the send screen
* Fix unit tests
* Fix e2e and integration tests
* Remove send/CurrencyDisplay component
* Replace diamond unicode character with Eth logo. Fix typos
Diffstat (limited to 'ui/app/components/pages')
6 files changed, 190 insertions, 42 deletions
diff --git a/ui/app/components/pages/confirm-token-transaction-base/confirm-token-transaction-base.component.js b/ui/app/components/pages/confirm-token-transaction-base/confirm-token-transaction-base.component.js index acaed383a..7f1fb4e49 100644 --- a/ui/app/components/pages/confirm-token-transaction-base/confirm-token-transaction-base.component.js +++ b/ui/app/components/pages/confirm-token-transaction-base/confirm-token-transaction-base.component.js @@ -1,12 +1,15 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' import ConfirmTransactionBase from '../confirm-transaction-base' +import UserPreferencedCurrencyDisplay from '../../user-preferenced-currency-display' import { formatCurrency, convertTokenToFiat, addFiat, roundExponential, } from '../../../helpers/confirm-transaction/util' +import { getWeiHexFromDecimalValue } from '../../../helpers/conversions.util' +import { ETH, PRIMARY } from '../../../constants/common' export default class ConfirmTokenTransactionBase extends Component { static contextTypes = { @@ -36,19 +39,48 @@ export default class ConfirmTokenTransactionBase extends Component { }) } - getSubtitle () { - const { currentCurrency, contractExchangeRate } = this.props + renderSubtitleComponent () { + const { contractExchangeRate, tokenAmount } = this.props - if (typeof contractExchangeRate === 'undefined') { - return this.context.t('noConversionRateAvailable') - } else { - const fiatTransactionAmount = this.getFiatTransactionAmount() - const roundedFiatTransactionAmount = roundExponential(fiatTransactionAmount) - return formatCurrency(roundedFiatTransactionAmount, currentCurrency) - } + const decimalEthValue = (tokenAmount * contractExchangeRate) || 0 + const hexWeiValue = getWeiHexFromDecimalValue({ + value: decimalEthValue, + fromCurrency: ETH, + fromDenomination: ETH, + }) + + return typeof contractExchangeRate === 'undefined' + ? ( + <span> + { this.context.t('noConversionRateAvailable') } + </span> + ) : ( + <UserPreferencedCurrencyDisplay + value={hexWeiValue} + type={PRIMARY} + showEthLogo + hideLabel + /> + ) + } + + renderPrimaryTotalTextOverride () { + const { tokenAmount, tokenSymbol, ethTransactionTotal } = this.props + const tokensText = `${tokenAmount} ${tokenSymbol}` + + return ( + <div> + <span>{ `${tokensText} + ` }</span> + <img + src="/images/eth.svg" + height="18" + /> + <span>{ ethTransactionTotal }</span> + </div> + ) } - getFiatTotalTextOverride () { + getSecondaryTotalTextOverride () { const { fiatTransactionTotal, currentCurrency, contractExchangeRate } = this.props if (typeof contractExchangeRate === 'undefined') { @@ -67,7 +99,6 @@ export default class ConfirmTokenTransactionBase extends Component { tokenAddress, tokenSymbol, tokenAmount, - ethTransactionTotal, ...restProps } = this.props @@ -78,9 +109,9 @@ export default class ConfirmTokenTransactionBase extends Component { toAddress={toAddress} identiconAddress={tokenAddress} title={tokensText} - subtitle={this.getSubtitle()} - ethTotalTextOverride={`${tokensText} + \u2666 ${ethTransactionTotal}`} - fiatTotalTextOverride={this.getFiatTotalTextOverride()} + subtitleComponent={this.renderSubtitleComponent()} + primaryTotalTextOverride={this.renderPrimaryTotalTextOverride()} + secondaryTotalTextOverride={this.getSecondaryTotalTextOverride()} {...restProps} /> ) diff --git a/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.component.js b/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.component.js index 707dad62d..c92867afe 100644 --- a/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.component.js +++ b/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.component.js @@ -1,7 +1,6 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' import ConfirmPageContainer, { ConfirmDetailRow } from '../../confirm-page-container' -import { formatCurrency } from '../../../helpers/confirm-transaction/util' import { isBalanceSufficient } from '../../send/send.utils' import { DEFAULT_ROUTE } from '../../../routes' import { @@ -9,6 +8,8 @@ import { TRANSACTION_ERROR_KEY, } from '../../../constants/error-keys' import { CONFIRMED_STATUS, DROPPED_STATUS } from '../../../constants/transactions' +import UserPreferencedCurrencyDisplay from '../../user-preferenced-currency-display' +import { PRIMARY, SECONDARY } from '../../../constants/common' export default class ConfirmTransactionBase extends Component { static contextTypes = { @@ -36,7 +37,9 @@ export default class ConfirmTransactionBase extends Component { fiatTransactionTotal: PropTypes.string, fromAddress: PropTypes.string, fromName: PropTypes.string, - hexGasTotal: PropTypes.string, + hexTransactionAmount: PropTypes.string, + hexTransactionFee: PropTypes.string, + hexTransactionTotal: PropTypes.string, isTxReprice: PropTypes.bool, methodData: PropTypes.object, nonce: PropTypes.string, @@ -59,8 +62,8 @@ export default class ConfirmTransactionBase extends Component { detailsComponent: PropTypes.node, errorKey: PropTypes.string, errorMessage: PropTypes.string, - ethTotalTextOverride: PropTypes.string, - fiatTotalTextOverride: PropTypes.string, + primaryTotalTextOverride: PropTypes.oneOfType([PropTypes.string, PropTypes.node]), + secondaryTotalTextOverride: PropTypes.string, hideData: PropTypes.bool, hideDetails: PropTypes.bool, hideSubtitle: PropTypes.bool, @@ -70,8 +73,10 @@ export default class ConfirmTransactionBase extends Component { onEditGas: PropTypes.func, onSubmit: PropTypes.func, subtitle: PropTypes.string, + subtitleComponent: PropTypes.node, summaryComponent: PropTypes.node, title: PropTypes.string, + titleComponent: PropTypes.node, valid: PropTypes.bool, warning: PropTypes.string, } @@ -105,7 +110,7 @@ export default class ConfirmTransactionBase extends Component { const { balance, conversionRate, - hexGasTotal, + hexTransactionFee, txData: { simulationFails, txParams: { @@ -116,7 +121,7 @@ export default class ConfirmTransactionBase extends Component { const insufficientBalance = balance && !isBalanceSufficient({ amount, - gasTotal: hexGasTotal || '0x0', + gasTotal: hexTransactionFee || '0x0', balance, conversionRate, }) @@ -153,13 +158,10 @@ export default class ConfirmTransactionBase extends Component { renderDetails () { const { detailsComponent, - fiatTransactionFee, - ethTransactionFee, - currentCurrency, - fiatTransactionTotal, - ethTransactionTotal, - fiatTotalTextOverride, - ethTotalTextOverride, + primaryTotalTextOverride, + secondaryTotalTextOverride, + hexTransactionFee, + hexTransactionTotal, hideDetails, } = this.props @@ -167,16 +169,13 @@ export default class ConfirmTransactionBase extends Component { return null } - const formattedCurrency = formatCurrency(fiatTransactionTotal, currentCurrency) - return ( detailsComponent || ( <div className="confirm-page-container-content__details"> <div className="confirm-page-container-content__gas-fee"> <ConfirmDetailRow label="Gas Fee" - fiatText={formatCurrency(fiatTransactionFee, currentCurrency)} - ethText={`\u2666 ${ethTransactionFee}`} + value={hexTransactionFee} headerText="Edit" headerTextClassName="confirm-detail-row__header-text--edit" onHeaderClick={() => this.handleEditGas()} @@ -185,11 +184,12 @@ export default class ConfirmTransactionBase extends Component { <div> <ConfirmDetailRow label="Total" - fiatText={fiatTotalTextOverride || formattedCurrency} - ethText={ethTotalTextOverride || `\u2666 ${ethTransactionTotal}`} + value={hexTransactionTotal} + primaryText={primaryTotalTextOverride} + secondaryText={secondaryTotalTextOverride} headerText="Amount + Gas Fee" headerTextClassName="confirm-detail-row__header-text--total" - fiatTextColor="#2f9ae0" + primaryValueTextColor="#2f9ae0" /> </div> </div> @@ -311,6 +311,43 @@ export default class ConfirmTransactionBase extends Component { } } + renderTitleComponent () { + const { title, titleComponent, hexTransactionAmount } = this.props + + // Title string passed in by props takes priority + if (title) { + return null + } + + return titleComponent || ( + <UserPreferencedCurrencyDisplay + value={hexTransactionAmount} + type={PRIMARY} + showEthLogo + ethLogoHeight="26" + hideLabel + /> + ) + } + + renderSubtitleComponent () { + const { subtitle, subtitleComponent, hexTransactionAmount } = this.props + + // Subtitle string passed in by props takes priority + if (subtitle) { + return null + } + + return subtitleComponent || ( + <UserPreferencedCurrencyDisplay + value={hexTransactionAmount} + type={SECONDARY} + showEthLogo + hideLabel + /> + ) + } + render () { const { isTxReprice, @@ -319,12 +356,9 @@ export default class ConfirmTransactionBase extends Component { toName, toAddress, methodData, - ethTransactionAmount, - fiatTransactionAmount, valid: propsValid = true, errorMessage, errorKey: propsErrorKey, - currentCurrency, action, title, subtitle, @@ -341,7 +375,6 @@ export default class ConfirmTransactionBase extends Component { const { submitting, submitError } = this.state const { name } = methodData - const fiatConvertedAmount = formatCurrency(fiatTransactionAmount, currentCurrency) const { valid, errorKey } = this.getErrorKey() return ( @@ -352,8 +385,10 @@ export default class ConfirmTransactionBase extends Component { toAddress={toAddress} showEdit={onEdit && !isTxReprice} action={action || name || this.context.t('unknownFunction')} - title={title || `${fiatConvertedAmount} ${currentCurrency.toUpperCase()}`} - subtitle={subtitle || `\u2666 ${ethTransactionAmount}`} + title={title} + titleComponent={this.renderTitleComponent()} + subtitle={subtitle} + subtitleComponent={this.renderSubtitleComponent()} hideSubtitle={hideSubtitle} summaryComponent={summaryComponent} detailsComponent={this.renderDetails()} diff --git a/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.container.js b/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.container.js index b34067686..c366d5137 100644 --- a/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.container.js +++ b/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.container.js @@ -36,7 +36,9 @@ const mapStateToProps = (state, props) => { fiatTransactionAmount, fiatTransactionFee, fiatTransactionTotal, - hexGasTotal, + hexTransactionAmount, + hexTransactionFee, + hexTransactionTotal, tokenData, methodData, txData, @@ -87,7 +89,9 @@ const mapStateToProps = (state, props) => { fiatTransactionAmount, fiatTransactionFee, fiatTransactionTotal, - hexGasTotal, + hexTransactionAmount, + hexTransactionFee, + hexTransactionTotal, txData, tokenData, methodData, diff --git a/ui/app/components/pages/settings/settings-tab/index.scss b/ui/app/components/pages/settings/settings-tab/index.scss index 76a0cec6f..3bf840c86 100644 --- a/ui/app/components/pages/settings/settings-tab/index.scss +++ b/ui/app/components/pages/settings/settings-tab/index.scss @@ -48,4 +48,22 @@ border-color: $ecstasy; } } + + &__radio-buttons { + display: flex; + align-items: center; + } + + &__radio-button { + display: flex; + align-items: center; + + &:not(:last-child) { + margin-right: 16px; + } + } + + &__radio-label { + padding-left: 4px; + } } diff --git a/ui/app/components/pages/settings/settings-tab/settings-tab.component.js b/ui/app/components/pages/settings/settings-tab/settings-tab.component.js index 9da624f56..a9e2a723e 100644 --- a/ui/app/components/pages/settings/settings-tab/settings-tab.component.js +++ b/ui/app/components/pages/settings/settings-tab/settings-tab.component.js @@ -55,6 +55,8 @@ export default class SettingsTab extends PureComponent { sendHexData: PropTypes.bool, currentCurrency: PropTypes.string, conversionDate: PropTypes.number, + useETHAsPrimaryCurrency: PropTypes.bool, + setUseETHAsPrimaryCurrencyPreference: PropTypes.func, } state = { @@ -339,6 +341,56 @@ export default class SettingsTab extends PureComponent { ) } + renderUseEthAsPrimaryCurrency () { + const { t } = this.context + const { useETHAsPrimaryCurrency, setUseETHAsPrimaryCurrencyPreference } = this.props + + return ( + <div className="settings-page__content-row"> + <div className="settings-page__content-item"> + <span>{ t('primaryCurrencySetting') }</span> + <div className="settings-page__content-description"> + { t('primaryCurrencySettingDescription') } + </div> + </div> + <div className="settings-page__content-item"> + <div className="settings-page__content-item-col"> + <div className="settings-tab__radio-buttons"> + <div className="settings-tab__radio-button"> + <input + type="radio" + id="eth-primary-currency" + onChange={() => setUseETHAsPrimaryCurrencyPreference(true)} + checked={Boolean(useETHAsPrimaryCurrency)} + /> + <label + htmlFor="eth-primary-currency" + className="settings-tab__radio-label" + > + { t('eth') } + </label> + </div> + <div className="settings-tab__radio-button"> + <input + type="radio" + id="fiat-primary-currency" + onChange={() => setUseETHAsPrimaryCurrencyPreference(false)} + checked={!useETHAsPrimaryCurrency} + /> + <label + htmlFor="fiat-primary-currency" + className="settings-tab__radio-label" + > + { t('fiat') } + </label> + </div> + </div> + </div> + </div> + </div> + ) + } + render () { const { warning, isMascara } = this.props @@ -346,6 +398,7 @@ export default class SettingsTab extends PureComponent { <div className="settings-page__content"> { warning && <div className="settings-tab__error">{ warning }</div> } { this.renderCurrentConversion() } + { this.renderUseEthAsPrimaryCurrency() } { this.renderCurrentLocale() } { this.renderNewRpcUrl() } { this.renderStateLogs() } diff --git a/ui/app/components/pages/settings/settings-tab/settings-tab.container.js b/ui/app/components/pages/settings/settings-tab/settings-tab.container.js index 665b56f5c..de30f309c 100644 --- a/ui/app/components/pages/settings/settings-tab/settings-tab.container.js +++ b/ui/app/components/pages/settings/settings-tab/settings-tab.container.js @@ -11,7 +11,9 @@ import { updateCurrentLocale, setFeatureFlag, showModal, + setUseETHAsPrimaryCurrencyPreference, } from '../../../../actions' +import { preferencesSelector } from '../../../../selectors' const mapStateToProps = state => { const { appState: { warning }, metamask } = state @@ -24,6 +26,7 @@ const mapStateToProps = state => { isMascara, currentLocale, } = metamask + const { useETHAsPrimaryCurrency } = preferencesSelector(state) return { warning, @@ -34,6 +37,7 @@ const mapStateToProps = state => { useBlockie, sendHexData, provider, + useETHAsPrimaryCurrency, } } @@ -50,6 +54,9 @@ const mapDispatchToProps = dispatch => { }, setHexDataFeatureFlag: shouldShow => dispatch(setFeatureFlag('sendHexData', shouldShow)), showResetAccountConfirmationModal: () => dispatch(showModal({ name: 'CONFIRM_RESET_ACCOUNT' })), + setUseETHAsPrimaryCurrencyPreference: value => { + return dispatch(setUseETHAsPrimaryCurrencyPreference(value)) + }, } } |