1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-23 09:52:26 +01:00

Add token selection to the send screen (#6445)

* Move send to pages/

* Fix unit tests

* Finish UI

* Integrate asset dropdown to send actions

* Remove console.log

* Hide asset change during edit

* Enable switch from send token to seand eth

* Enable switching from token to eth when editing

* Fix linter

* Fixing test

* Fix unit tests

* Fix linter

* Fix react warning; remove console.log

* fix flat test

* Add metrics

* Address code review comments

* Consistent spacing between send screen form rows.

* Reduce height of gas buttons on send screen.

* Make send screen gas button height dependent on size of contents.
This commit is contained in:
Chi Kei Chan 2019-04-17 12:15:13 -07:00 committed by Dan J Miller
parent a844eb20da
commit 931aaeb700
137 changed files with 444 additions and 134 deletions

View File

@ -139,6 +139,9 @@
"approved": {
"message": "Approved"
},
"asset": {
"message": "Asset"
},
"attemptingConnect": {
"message": "Attempting to connect to blockchain."
},
@ -1351,6 +1354,9 @@
"selectAnAccountHelp": {
"message": "Select the account to view in MetaMask"
},
"selectAnAsset": {
"message": "Select an Asset"
},
"selectAHigherGasFee": {
"message": "Select a higher gas fee to accelerate the processing of your transaction.*"
},

View File

@ -72,7 +72,7 @@ async function runSendFlowTest (assert, done) {
const sendToAccountAddress = sendToFieldInput.val()
assert.equal(sendToAccountAddress, '0x2f8D4a878cFA04A6E60D46362f5644DeAb66572D', 'send to dropdown selects the correct address')
const sendAmountField = await queryAsync($, '.send-v2__form-row:eq(2)')
const sendAmountField = await queryAsync($, '.send-v2__form-row:eq(3)')
sendAmountField.find('.unit-input')[0].click()
const sendAmountFieldInput = await findAsync(sendAmountField, '.unit-input__input')
@ -115,7 +115,7 @@ async function runSendFlowTest (assert, done) {
sendToFieldInputInEdit[0].focus()
sendToFieldInputInEdit.val('0xd85a4b6a394794842887b8284293d69163007bbb')
const sendAmountFieldInEdit = await queryAsync($, '.send-v2__form-row:eq(2)')
const sendAmountFieldInEdit = await queryAsync($, '.send-v2__form-row:eq(3)')
sendAmountFieldInEdit.find('.unit-input')[0].click()
const sendAmountFieldInputInEdit = sendAmountFieldInEdit.find('.unit-input__input')

View File

@ -18,11 +18,11 @@ const {
MIN_GAS_PRICE_DEC,
MIN_GAS_LIMIT_DEC,
MIN_GAS_PRICE_GWEI,
} = require('../send/send.constants')
} = require('../../../pages/send/send.constants')
const {
isBalanceSufficient,
} = require('../send/send.utils')
} = require('../../../pages/send/send.utils')
const {
conversionUtil,
@ -47,7 +47,7 @@ const {
const {
getGasPrice,
getGasLimit,
} = require('../send/send.selectors')
} = require('../../../pages/send/send.selectors')
function mapStateToProps (state) {
const selectedToken = getSelectedToken(state)

View File

@ -10,7 +10,7 @@ const networkMap = require('ethjs-ens/lib/network-map.json')
const ensRE = /.+\..+$/
const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'
const connect = require('react-redux').connect
const ToAutoComplete = require('./send/to-autocomplete').default
const ToAutoComplete = require('../../pages/send/to-autocomplete').default
const log = require('loglevel')
const { isValidENSAddress } = require('../../helpers/utils/util')

View File

@ -63,7 +63,7 @@ import {
import {
calcGasTotal,
isBalanceSufficient,
} from '../../send/send.utils'
} from '../../../../pages/send/send.utils'
import { addHexPrefix } from 'ethereumjs-util'
import { getAdjacentGasPrices, extrapolateY } from '../gas-price-chart/gas-price-chart.utils'

View File

@ -99,15 +99,13 @@
}
&__loading-container {
height: 78px;
height: 54px;
}
.button-group__button, .button-group__button--active {
height: 78px;
background: white;
color: $scorpion;
padding-top: 9px;
padding-left: 8.5px;
padding: 2px 8.5px 4px 8.5px;
@media screen and (max-width: $break-small) {
padding-left: 4px;

View File

@ -2,7 +2,7 @@ import React, { Component } from 'react'
import PropTypes from 'prop-types'
import BigNumber from 'bignumber.js'
import GasModalCard from '../../customize-gas-modal/gas-modal-card'
import { MIN_GAS_PRICE_GWEI } from '../../send/send.constants'
import { MIN_GAS_PRICE_GWEI } from '../../../../pages/send/send.constants'
import Button from '../../../ui/button'
import {

View File

@ -15,7 +15,7 @@ import {
setCustomGasLimit,
} from '../../../ducks/gas/gas.duck'
import { getIsMainnet, preferencesSelector, getSelectedAddress, conversionRateSelector } from '../../../selectors/selectors'
import { isBalanceSufficient } from '../send/send.utils'
import { isBalanceSufficient } from '../../../pages/send/send.utils'
const mapStateToProps = (state, ownProps) => {
const { metamask: { knownMethodData, accounts } } = state

View File

@ -1,6 +1,6 @@
import React, { PureComponent } from 'react'
import PropTypes from 'prop-types'
import AccountListItem from '../../app/send/account-list-item/account-list-item.component'
import AccountListItem from '../../../pages/send/account-list-item/account-list-item.component'
export default class AccountDropdownMini extends PureComponent {
static propTypes = {

View File

@ -2,7 +2,7 @@ import React from 'react'
import assert from 'assert'
import { shallow } from 'enzyme'
import AccountDropdownMini from '../account-dropdown-mini.component'
import AccountListItem from '../../../app/send/account-list-item/account-list-item.component'
import AccountListItem from '../../../../pages/send/account-list-item/account-list-item.component'
describe('AccountDropdownMini', () => {
it('should render an account with an icon', () => {

View File

@ -1,7 +1,7 @@
import React, { PureComponent } from 'react'
import PropTypes from 'prop-types'
import classnames from 'classnames'
import { removeLeadingZeroes } from '../../app/send/send.utils'
import { removeLeadingZeroes } from '../../../pages/send/send.utils'
/**
* Component that attaches a suffix or unit of measurement trailing user input, ex. 'ETH'. Also

View File

@ -549,7 +549,7 @@
}
&__form-row {
margin: 14.5px 18px 0px;
margin: 8px 18px 0px;
position: relative;
display: flex;
flex-flow: row;
@ -592,8 +592,8 @@
flex: 0 0 auto;
}
&__from-dropdown {
height: 73px;
&__from-dropdown,
&__asset-dropdown {
width: 100%;
border: 1px solid $alto;
border-radius: 4px;
@ -628,6 +628,104 @@
}
}
&__from-dropdown {
height: 73px;
}
&__asset-dropdown {
height: 62px;
border: none;
&__asset {
display: flex;
flex-flow: row nowrap;
align-items: center;
padding: 10px 8px;
cursor: pointer;
&:hover {
background-color: rgba($alto, 0.2);
}
}
&__asset-icon {
.identicon {
border: 1px solid $alto;
}
}
&__asset-data {
display: flex;
flex-flow: column nowrap;
margin-left: 8px;
}
&__symbol {
font-size: 16px;
margin-bottom: 2px;
}
&__name {
display: flex;
flex-flow: row nowrap;
font-size: 12px;
&__label {
margin-right: .25rem;
}
}
&__close-area {
z-index: 2000;
}
&__list {
z-index: 2050;
position: absolute;
height: 220px;
width: 100%;
border: 1px solid $geyser;
border-radius: 4px;
background-color: $white;
box-shadow: 0 3px 6px 0 rgba(0 ,0 ,0 ,.11);
top: 55px;
left: 0;
box-sizing: content-box;
overflow-y: scroll;
}
&__input-wrapper {
border: 1px solid $alto;
border-radius: 4px;
&--opened {
position: relative;
z-index: 2050;
}
.send-v2__asset-dropdown__asset {
&:hover {
background-color: $white;
}
}
}
&__input {
z-index: 1025;
position: relative;
height: 54px;
width: 100%;
border: none;
border-radius: 4px;
background-color: $white;
color: $tundora;
padding: 10px;
font-family: Roboto;
font-size: 16px;
line-height: 21px;
}
}
&__to-autocomplete {
position: relative;

View File

@ -154,9 +154,26 @@ function reduceMetamask (state, action) {
return newState
case actions.SET_SELECTED_TOKEN:
return extend(metamaskState, {
newState = extend(metamaskState, {
selectedTokenAddress: action.value,
})
const newSend = extend(metamaskState.send)
if (metamaskState.send.editingTransactionId && !action.value) {
delete newSend.token
const unapprovedTx = newState.unapprovedTxs[newSend.editingTransactionId] || {}
const txParams = unapprovedTx.txParams || {}
newState.unapprovedTxs = extend(newState.unapprovedTxs, {
[newSend.editingTransactionId]: extend(unapprovedTx, {
txParams: extend(txParams, { data: '' }),
}),
})
newSend.tokenBalance = null
newSend.balance = '0'
}
newState.send = newSend
return newState
case actions.SET_ACCOUNT_LABEL:
const account = action.value.account

View File

@ -4,7 +4,7 @@ import PropTypes from 'prop-types'
import { ENVIRONMENT_TYPE_NOTIFICATION } from '../../../../app/scripts/lib/enums'
import { getEnvironmentType } from '../../../../app/scripts/lib/util'
import ConfirmPageContainer, { ConfirmDetailRow } from '../../components/app/confirm-page-container'
import { isBalanceSufficient } from '../../components/app/send/send.utils'
import { isBalanceSufficient } from '../send/send.utils'
import { DEFAULT_ROUTE, CONFIRM_TRANSACTION_ROUTE } from '../../helpers/constants/routes'
import {
INSUFFICIENT_FUNDS_ERROR_KEY,

View File

@ -14,9 +14,9 @@ import {
GAS_LIMIT_TOO_LOW_ERROR_KEY,
} from '../../helpers/constants/error-keys'
import { getHexGasTotal } from '../../helpers/utils/confirm-tx.util'
import { isBalanceSufficient, calcGasTotal } from '../../components/app/send/send.utils'
import { isBalanceSufficient, calcGasTotal } from '../send/send.utils'
import { conversionGreaterThan } from '../../helpers/utils/conversion-util'
import { MIN_GAS_LIMIT_DEC } from '../../components/app/send/send.constants'
import { MIN_GAS_LIMIT_DEC } from '../send/send.constants'
import { checksumAddress, addressSlicer, valuesFor } from '../../helpers/utils/util'
import {getMetaMaskAccounts, getAdvancedInlineGasShown, preferencesSelector, getIsMainnet} from '../../selectors/selectors'

View File

@ -3,7 +3,7 @@ import { compose } from 'recompose'
import { connect } from 'react-redux'
import { withRouter } from 'react-router-dom'
import { unconfirmedTransactionsCountSelector } from '../../selectors/confirm-transaction'
``
const mapStateToProps = state => {
const { metamask, appState } = state
const {

View File

@ -10,7 +10,7 @@ import { getMetaMaskAccounts, getNetworkIdentifier } from '../../selectors/selec
// init
import FirstTimeFlow from '../first-time-flow'
// accounts
const SendTransactionScreen = require('../../components/app/send/send.container')
const SendTransactionScreen = require('../send/send.container')
const ConfirmTransaction = require('../confirm-transaction')
// slideout menu

View File

@ -1,11 +1,11 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import classnames from 'classnames'
import { checksumAddress } from '../../../../helpers/utils/util'
import Identicon from '../../../ui/identicon'
import UserPreferencedCurrencyDisplay from '../../user-preferenced-currency-display'
import { PRIMARY, SECONDARY } from '../../../../helpers/constants/common'
import Tooltip from '../../../ui/tooltip-v2'
import { checksumAddress } from '../../../helpers/utils/util'
import Identicon from '../../../components/ui/identicon'
import UserPreferencedCurrencyDisplay from '../../../components/app/user-preferenced-currency-display'
import { PRIMARY, SECONDARY } from '../../../helpers/constants/common'
import Tooltip from '../../../components/ui/tooltip-v2'
export default class AccountListItem extends Component {

View File

@ -8,7 +8,7 @@ import {
getIsMainnet,
isBalanceCached,
preferencesSelector,
} from '../../../../selectors/selectors'
} from '../../../selectors/selectors'
import AccountListItem from './account-list-item.component'
export default connect(mapStateToProps)(AccountListItem)

View File

@ -3,15 +3,15 @@ import assert from 'assert'
import { shallow } from 'enzyme'
import sinon from 'sinon'
import proxyquire from 'proxyquire'
import Identicon from '../../../../ui/identicon'
import UserPreferencedCurrencyDisplay from '../../../user-preferenced-currency-display'
import Identicon from '../../../../components/ui/identicon'
import UserPreferencedCurrencyDisplay from '../../../../components/app/user-preferenced-currency-display'
const utilsMethodStubs = {
checksumAddress: sinon.stub().returns('mockCheckSumAddress'),
}
const AccountListItem = proxyquire('../account-list-item.component.js', {
'../../../../helpers/utils/util': utilsMethodStubs,
'../../../helpers/utils/util': utilsMethodStubs,
}).default

View File

@ -15,7 +15,7 @@ proxyquire('../account-list-item.container.js', {
getCurrentCurrency: () => `mockCurrentCurrency`,
getNativeCurrency: () => `mockNativeCurrency`,
},
'../../../../selectors/selectors': {
'../../../selectors/selectors': {
isBalanceCached: () => `mockBalanceIsCached`,
preferencesSelector: ({ showFiatInTestnets }) => ({
showFiatInTestnets,

View File

@ -10,11 +10,11 @@ import { calcMaxAmount } from './amount-max-button.utils.js'
import {
updateSendAmount,
setMaxModeTo,
} from '../../../../../../store/actions'
} from '../../../../../store/actions'
import AmountMaxButton from './amount-max-button.component'
import {
updateSendErrors,
} from '../../../../../../ducks/send/send.duck'
} from '../../../../../ducks/send/send.duck'
export default connect(mapStateToProps, mapDispatchToProps)(AmountMaxButton)

View File

@ -1,7 +1,7 @@
const {
multiplyCurrencies,
subtractCurrencies,
} = require('../../../../../../helpers/utils/conversion-util')
} = require('../../../../../helpers/utils/conversion-util')
const ethUtil = require('ethereumjs-util')
function calcMaxAmount ({ balance, gasTotal, selectedToken, tokenBalance }) {

View File

@ -29,8 +29,8 @@ proxyquire('../amount-max-button.container.js', {
},
'./amount-max-button.selectors.js': { getMaxModeOn: (s) => `mockMaxModeOn:${s}` },
'./amount-max-button.utils.js': { calcMaxAmount: (mockObj) => mockObj.val + 1 },
'../../../../../../store/actions': actionSpies,
'../../../../../../ducks/send/send.duck': duckActionSpies,
'../../../../../store/actions': actionSpies,
'../../../../../ducks/send/send.duck': duckActionSpies,
})
describe('amount-max-button container', () => {

View File

@ -2,8 +2,8 @@ import React, { Component } from 'react'
import PropTypes from 'prop-types'
import SendRowWrapper from '../send-row-wrapper'
import AmountMaxButton from './amount-max-button'
import UserPreferencedCurrencyInput from '../../../user-preferenced-currency-input'
import UserPreferencedTokenInput from '../../../user-preferenced-token-input'
import UserPreferencedCurrencyInput from '../../../../components/app/user-preferenced-currency-input'
import UserPreferencedTokenInput from '../../../../components/app/user-preferenced-token-input'
export default class SendAmountRow extends Component {

View File

@ -17,10 +17,10 @@ import { getAmountErrorObject, getGasFeeErrorObject } from '../../send.utils'
import {
setMaxModeTo,
updateSendAmount,
} from '../../../../../store/actions'
} from '../../../../store/actions'
import {
updateSendErrors,
} from '../../../../../ducks/send/send.duck'
} from '../../../../ducks/send/send.duck'
import SendAmountRow from './send-amount-row.component'
export default connect(mapStateToProps, mapDispatchToProps)(SendAmountRow)

View File

@ -6,7 +6,7 @@ import SendAmountRow from '../send-amount-row.component.js'
import SendRowWrapper from '../../send-row-wrapper/send-row-wrapper.component'
import AmountMaxButton from '../amount-max-button/amount-max-button.container'
import UserPreferencedTokenInput from '../../../../user-preferenced-token-input'
import UserPreferencedTokenInput from '../../../../../components/app/user-preferenced-token-input'
const propsMethodSpies = {
setMaxModeTo: sinon.spy(),

View File

@ -37,8 +37,8 @@ proxyquire('../send-amount-row.container.js', {
getAmountErrorObject: (mockDataObject) => ({ ...mockDataObject, mockChange: true }),
getGasFeeErrorObject: (mockDataObject) => ({ ...mockDataObject, mockGasFeeErrorChange: true }),
},
'../../../../../store/actions': actionSpies,
'../../../../../ducks/send/send.duck': duckActionSpies,
'../../../../store/actions': actionSpies,
'../../../../ducks/send/send.duck': duckActionSpies,
})
describe('send-amount-row container', () => {

View File

@ -0,0 +1 @@
export { default } from './send-asset-row.container'

View File

@ -0,0 +1,152 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import SendRowWrapper from '../send-row-wrapper'
import Identicon from '../../../../components/ui/identicon/identicon.component'
import TokenBalance from '../../../../components/ui/token-balance'
import UserPreferencedCurrencyDisplay from '../../../../components/app/user-preferenced-currency-display'
import {PRIMARY} from '../../../../helpers/constants/common'
export default class SendAssetRow extends Component {
static propTypes = {
tokens: PropTypes.arrayOf(
PropTypes.shape({
address: PropTypes.string,
decimals: PropTypes.string,
symbol: PropTypes.string,
})
).isRequired,
accounts: PropTypes.object.isRequired,
selectedAddress: PropTypes.string.isRequired,
selectedTokenAddress: PropTypes.string,
setSelectedToken: PropTypes.func.isRequired,
}
static contextTypes = {
t: PropTypes.func,
metricsEvent: PropTypes.func,
}
state = {
isShowingDropdown: false,
}
openDropdown = () => this.setState({ isShowingDropdown: true })
closeDropdown = () => this.setState({ isShowingDropdown: false })
selectToken = address => {
this.setState({
isShowingDropdown: false,
}, () => {
this.context.metricsEvent({
eventOpts: {
category: 'Transactions',
action: 'Send Screen',
name: 'User clicks "Assets" dropdown',
},
customVariables: {
assetSelected: address ? 'ERC20' : 'ETH',
},
})
this.props.setSelectedToken(address)
})
}
render () {
const { t } = this.context
return (
<SendRowWrapper label={`${t('asset')}:`}>
<div className="send-v2__asset-dropdown">
{ this.renderSelectedToken() }
{ this.renderAssetDropdown() }
</div>
</SendRowWrapper>
)
}
renderSelectedToken () {
const { selectedTokenAddress } = this.props
const token = this.props.tokens.find(({ address }) => address === selectedTokenAddress)
return (
<div
className="send-v2__asset-dropdown__input-wrapper"
onClick={this.openDropdown}
>
{ token ? this.renderAsset(token) : this.renderEth() }
</div>
)
}
renderAssetDropdown () {
return this.state.isShowingDropdown && (
<div>
<div
className="send-v2__asset-dropdown__close-area"
onClick={this.closeDropdown}
/>
<div className="send-v2__asset-dropdown__list">
{ this.renderEth() }
{ this.props.tokens.map(token => this.renderAsset(token)) }
</div>
</div>
)
}
renderEth () {
const { t } = this.context
const { accounts, selectedAddress } = this.props
const balanceValue = accounts[selectedAddress] ? accounts[selectedAddress].balance : ''
return (
<div
className="send-v2__asset-dropdown__asset"
onClick={() => this.selectToken()}
>
<div className="send-v2__asset-dropdown__asset-icon">
<Identicon diameter={36} />
</div>
<div className="send-v2__asset-dropdown__asset-data">
<div className="send-v2__asset-dropdown__symbol">ETH</div>
<div className="send-v2__asset-dropdown__name">
<span className="send-v2__asset-dropdown__name__label">{`${t('balance')}:`}</span>
<UserPreferencedCurrencyDisplay
value={balanceValue}
type={PRIMARY}
/>
</div>
</div>
</div>
)
}
renderAsset (token) {
const { address, symbol } = token
const { t } = this.context
return (
<div
key={address} className="send-v2__asset-dropdown__asset"
onClick={() => this.selectToken(address)}
>
<div className="send-v2__asset-dropdown__asset-icon">
<Identicon address={address} diameter={36} />
</div>
<div className="send-v2__asset-dropdown__asset-data">
<div className="send-v2__asset-dropdown__symbol">
{ symbol }
</div>
<div className="send-v2__asset-dropdown__name">
<span className="send-v2__asset-dropdown__name__label">{`${t('balance')}:`}</span>
<TokenBalance
token={token}
withSymbol
/>
</div>
</div>
</div>
)
}
}

View File

@ -0,0 +1,21 @@
import { connect } from 'react-redux'
import SendAssetRow from './send-asset-row.component'
import {getMetaMaskAccounts} from '../../../../selectors/selectors'
import { setSelectedToken } from '../../../../store/actions'
function mapStateToProps (state) {
return {
tokens: state.metamask.tokens,
selectedAddress: state.metamask.selectedAddress,
selectedTokenAddress: state.metamask.selectedTokenAddress,
accounts: getMetaMaskAccounts(state),
}
}
function mapDispatchToProps (dispatch) {
return {
setSelectedToken: address => dispatch(setSelectedToken(address)),
}
}
export default connect(mapStateToProps, mapDispatchToProps)(SendAssetRow)

View File

@ -1,11 +1,12 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import PageContainerContent from '../../../ui/page-container/page-container-content.component'
import PageContainerContent from '../../../components/ui/page-container/page-container-content.component'
import SendAmountRow from './send-amount-row'
import SendFromRow from './send-from-row'
import SendGasRow from './send-gas-row'
import SendHexDataRow from './send-hex-data-row'
import SendToRow from './send-to-row'
import SendAssetRow from './send-asset-row'
export default class SendContent extends Component {
@ -26,6 +27,7 @@ export default class SendContent extends Component {
updateGas={this.updateGas}
scanQrCode={ _ => this.props.scanQrCode()}
/>
<SendAssetRow />
<SendAmountRow updateGas={this.updateGas} />
<SendGasRow />
{(this.props.showHexData && (

View File

@ -1,7 +1,7 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import UserPreferencedCurrencyDisplay from '../../../../user-preferenced-currency-display'
import { PRIMARY, SECONDARY } from '../../../../../../helpers/constants/common'
import UserPreferencedCurrencyDisplay from '../../../../../components/app/user-preferenced-currency-display'
import { PRIMARY, SECONDARY } from '../../../../../helpers/constants/common'
export default class GasFeeDisplay extends Component {

View File

@ -2,7 +2,7 @@ import React from 'react'
import assert from 'assert'
import {shallow} from 'enzyme'
import GasFeeDisplay from '../gas-fee-display.component'
import UserPreferencedCurrencyDisplay from '../../../../../user-preferenced-currency-display'
import UserPreferencedCurrencyDisplay from '../../../../../../components/app/user-preferenced-currency-display'
import sinon from 'sinon'

View File

@ -2,8 +2,8 @@ import React, { Component } from 'react'
import PropTypes from 'prop-types'
import SendRowWrapper from '../send-row-wrapper'
import GasFeeDisplay from './gas-fee-display/gas-fee-display.component'
import GasPriceButtonGroup from '../../../gas-customization/gas-price-button-group'
import AdvancedGasInputs from '../../../gas-customization/advanced-gas-inputs'
import GasPriceButtonGroup from '../../../../components/app/gas-customization/gas-price-button-group'
import AdvancedGasInputs from '../../../../components/app/gas-customization/advanced-gas-inputs'
export default class SendGasRow extends Component {
@ -20,8 +20,8 @@ export default class SendGasRow extends Component {
gasButtonGroupShown: PropTypes.bool,
advancedInlineGasShown: PropTypes.bool,
resetGasButtons: PropTypes.func,
gasPrice: PropTypes.number,
gasLimit: PropTypes.number,
gasPrice: PropTypes.string,
gasLimit: PropTypes.string,
insufficientBalance: PropTypes.bool,
}

View File

@ -15,18 +15,18 @@ import {
getBasicGasEstimateLoadingStatus,
getRenderableEstimateDataForSmallButtonsFromGWEI,
getDefaultActiveButtonIndex,
} from '../../../../../selectors/custom-gas'
} from '../../../../selectors/custom-gas'
import {
showGasButtonGroup,
} from '../../../../../ducks/send/send.duck'
} from '../../../../ducks/send/send.duck'
import {
resetCustomData,
setCustomGasPrice,
setCustomGasLimit,
} from '../../../../../ducks/gas/gas.duck'
} from '../../../../ducks/gas/gas.duck'
import { getGasLoadingError, gasFeeIsInError, getGasButtonGroupShown } from './send-gas-row.selectors.js'
import { showModal, setGasPrice, setGasLimit, setGasTotal } from '../../../../../store/actions'
import { getAdvancedInlineGasShown, getCurrentEthBalance, getSelectedToken } from '../../../../../selectors/selectors'
import { showModal, setGasPrice, setGasLimit, setGasTotal } from '../../../../store/actions'
import { getAdvancedInlineGasShown, getCurrentEthBalance, getSelectedToken } from '../../../../selectors/selectors'
import SendGasRow from './send-gas-row.component'
export default connect(mapStateToProps, mapDispatchToProps, mergeProps)(SendGasRow)

View File

@ -6,7 +6,7 @@ import SendGasRow from '../send-gas-row.component.js'
import SendRowWrapper from '../../send-row-wrapper/send-row-wrapper.component'
import GasFeeDisplay from '../gas-fee-display/gas-fee-display.component'
import GasPriceButtonGroup from '../../../../gas-customization/gas-price-button-group'
import GasPriceButtonGroup from '../../../../../components/app/gas-customization/gas-price-button-group'
const propsMethodSpies = {
showCustomizeGasModal: sinon.spy(),

View File

@ -32,7 +32,7 @@ proxyquire('../send-gas-row.container.js', {
return () => ({})
},
},
'../../../../../selectors/selectors': {
'../../../../selectors/selectors': {
getCurrentEthBalance: (s) => `mockCurrentEthBalance:${s}`,
getAdvancedInlineGasShown: (s) => `mockAdvancedInlineGasShown:${s}`,
getSelectedToken: () => false,
@ -59,14 +59,14 @@ proxyquire('../send-gas-row.container.js', {
gasFeeIsInError: (s) => `mockGasFeeError:${s}`,
getGasButtonGroupShown: (s) => `mockGetGasButtonGroupShown:${s}`,
},
'../../../../../store/actions': actionSpies,
'../../../../../selectors/custom-gas': {
'../../../../store/actions': actionSpies,
'../../../../selectors/custom-gas': {
getBasicGasEstimateLoadingStatus: (s) => `mockBasicGasEstimateLoadingStatus:${s}`,
getRenderableEstimateDataForSmallButtonsFromGWEI: (s) => `mockGasButtonInfo:${s}`,
getDefaultActiveButtonIndex: (gasButtonInfo, gasPrice) => gasButtonInfo.length + gasPrice.length,
},
'../../../../../ducks/send/send.duck': sendDuckSpies,
'../../../../../ducks/gas/gas.duck': gasDuckSpies,
'../../../../ducks/send/send.duck': sendDuckSpies,
'../../../../ducks/gas/gas.duck': gasDuckSpies,
})
describe('send-gas-row container', () => {

View File

@ -1,7 +1,7 @@
import { connect } from 'react-redux'
import {
updateSendHexData,
} from '../../../../../store/actions'
} from '../../../../store/actions'
import SendHexDataRow from './send-hex-data-row.component'
export default connect(mapStateToProps, mapDispatchToProps)(SendHexDataRow)

View File

@ -1,7 +1,7 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import SendRowWrapper from '../send-row-wrapper'
import EnsInput from '../../../ens-input'
import EnsInput from '../../../../components/app/ens-input'
import { getToErrorObject, getToWarningObject } from './send-to-row.utils.js'
export default class SendToRow extends Component {

View File

@ -14,13 +14,13 @@ import {
} from './send-to-row.selectors.js'
import {
updateSendTo,
} from '../../../../../store/actions'
} from '../../../../store/actions'
import {
updateSendErrors,
updateSendWarnings,
openToDropdown,
closeToDropdown,
} from '../../../../../ducks/send/send.duck'
} from '../../../../ducks/send/send.duck'
import SendToRow from './send-to-row.component'
export default connect(mapStateToProps, mapDispatchToProps)(SendToRow)

View File

@ -4,8 +4,8 @@ const {
KNOWN_RECIPIENT_ADDRESS_ERROR,
INVALID_RECIPIENT_ADDRESS_NOT_ETH_NETWORK_ERROR,
} = require('../../send.constants')
const { isValidAddress, isEthNetwork } = require('../../../../../helpers/utils/util')
import { checkExistingAddresses } from '../../../../../pages/add-token/util'
const { isValidAddress, isEthNetwork } = require('../../../../helpers/utils/util')
import { checkExistingAddresses } from '../../../add-token/util'
const ethUtil = require('ethereumjs-util')
const contractMap = require('eth-contract-metadata')

View File

@ -16,7 +16,7 @@ const SendToRow = proxyquire('../send-to-row.component.js', {
}).default
import SendRowWrapper from '../../send-row-wrapper/send-row-wrapper.component'
import EnsInput from '../../../../ens-input'
import EnsInput from '../../../../../components/app/ens-input'
const propsMethodSpies = {
closeToDropdown: sinon.spy(),

View File

@ -36,8 +36,8 @@ proxyquire('../send-to-row.container.js', {
sendToIsInWarning: (s) => `mockInWarning:${s}`,
getTokens: (s) => `mockTokens:${s}`,
},
'../../../../../store/actions': actionSpies,
'../../../../../ducks/send/send.duck': duckActionSpies,
'../../../../store/actions': actionSpies,
'../../../../ducks/send/send.duck': duckActionSpies,
})
describe('send-to-row container', () => {

Some files were not shown because too many files have changed in this diff Show More