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

Lint fixes and alphabetization for i3725-refactor-send-component

This commit is contained in:
Dan 2018-04-26 22:08:14 -02:30
parent 8ff7806f1b
commit 91c201aa72
35 changed files with 368 additions and 403 deletions

View File

@ -12,7 +12,7 @@ export default class PageContainerContent extends Component {
<div className="page-container__content">
{this.props.children}
</div>
);
)
}
}

View File

@ -31,7 +31,7 @@ export default class PageContainerFooter extends Component {
</button>
</div>
);
)
}
}

View File

@ -29,7 +29,7 @@ export default class PageContainerHeader extends Component {
/>
</div>
);
)
}
}

View File

@ -8,12 +8,11 @@ export default class PageContainer extends Component {
};
render () {
console.log(`QQQQQQQQQQQQQQQQQ this.props.children`, this.props.children);
return (
<div className="page-container">
{this.props.children}
</div>
);
)
}
}

View File

@ -19,14 +19,14 @@ export default class AccountListItem extends Component {
render () {
const {
className,
account,
handleClick,
icon = null,
className,
conversionRate,
currentCurrency,
displayBalance = true,
displayAddress = false,
displayBalance = true,
handleClick,
icon = null,
} = this.props
const { name, address, balance } = account || {}
@ -36,32 +36,32 @@ export default class AccountListItem extends Component {
onClick={() => handleClick({ name, address, balance })}
>
<div className='account-list-item__top-row'>
<div className="account-list-item__top-row">
<Identicon
address={address}
className="account-list-item__identicon"
diameter={18}
className='account-list-item__identicon'
/>
<div className='account-list-item__account-name'>{ name || address }</div>
<div className="account-list-item__account-name">{ name || address }</div>
{icon && <div className='account-list-item__icon'>{ icon }</div>}
{icon && <div className="account-list-item__icon">{ icon }</div>}
</div>
{displayAddress && name && <div className='account-list-item__account-address'>
{displayAddress && name && <div className="account-list-item__account-address">
{ checksumAddress(address) }
</div>}
{displayBalance && <CurrencyDisplay
primaryCurrency='ETH'
convertedCurrency={currentCurrency}
value={balance}
className="account-list-item__account-balances"
conversionRate={conversionRate}
convertedBalanceClassName="account-list-item__account-secondary-balance"
convertedCurrency={currentCurrency}
primaryBalanceClassName="account-list-item__account-primary-balance"
primaryCurrency="ETH"
readOnly={true}
className='account-list-item__account-balances'
primaryBalanceClassName='account-list-item__account-primary-balance'
convertedBalanceClassName='account-list-item__account-secondary-balance'
value={balance}
/>}
</div>)

View File

@ -4,29 +4,29 @@ import PropTypes from 'prop-types'
export default class AmountMaxButton extends Component {
static propTypes = {
tokenBalance: PropTypes.string,
gasTotal: PropTypes.string,
balance: PropTypes.string,
gasTotal: PropTypes.string,
maxModeOn: PropTypes.bool,
selectedToken: PropTypes.object,
setAmountToMax: PropTypes.func,
setMaxModeTo: PropTypes.func,
maxModeOn: PropTypes.bool,
tokenBalance: PropTypes.string,
};
setAmountToMax = function () {
const {
balance,
tokenBalance,
selectedToken,
gasTotal,
selectedToken,
setAmountToMax,
tokenBalance,
} = this.props
setAmountToMax({
tokenBalance,
selectedToken,
balance,
gasTotal,
setAmountToMax,
selectedToken,
tokenBalance,
})
}
@ -35,7 +35,7 @@ export default class AmountMaxButton extends Component {
return (
<div
className='send-v2__amount-max'
className="send-v2__amount-max"
onClick={(event) => {
event.preventDefault()
setMaxModeTo(true)
@ -44,7 +44,7 @@ export default class AmountMaxButton extends Component {
>
{!maxModeOn ? this.context.t('max') : ''}
</div>
);
)
}
}

View File

@ -1,28 +1,29 @@
import { connect } from 'react-redux'
import {
getSelectedToken,
getGasTotal,
getTokenBalance,
getSelectedToken,
getSendFromBalance,
getTokenBalance,
} from '../../../send.selectors.js'
import { getMaxModeOn } from '../send-amount-row.selectors.js'
import { calcMaxAmount } from './amount-max-button.utils.js'
import {
updateSendAmount,
updateSendErrors,
setMaxModeTo,
} from '../../../actions'
import AmountMaxButton from './amount-max-button.component'
export default connect(mapStateToProps, mapDispatchToProps)(SendToRow)
export default connect(mapStateToProps, mapDispatchToProps)(AmountMaxButton)
function mapStateToProps (state) {
return {
selectedToken: getSelectedToken(state),
maxModeOn: getMaxModeOn(state),
gasTotal: getGasTotal(state),
tokenBalance: getTokenBalance(state),
balance: getSendFromBalance(state),
gasTotal: getGasTotal(state),
maxModeOn: getMaxModeOn(state),
selectedToken: getSelectedToken(state),
tokenBalance: getTokenBalance(state),
}
}
@ -31,7 +32,7 @@ function mapDispatchToProps (dispatch) {
setAmountToMax: maxAmountDataObject => {
updateSendErrors({ amount: null })
updateSendAmount(calcMaxAmount(maxAmountDataObject))
}
},
setMaxModeTo: bool => dispatch(setMaxModeTo(bool)),
}
}

View File

@ -18,5 +18,5 @@ function calcMaxAmount ({ balance, gasTotal, selectedToken, tokenBalance }) {
}
module.exports = {
calcMaxAmount
calcMaxAmount,
}

View File

@ -7,22 +7,26 @@ import CurrencyDisplay from '../../../send/currency-display'
export default class SendAmountRow extends Component {
static propTypes = {
amount: PropTypes.string,
amountConversionRate: PropTypes.number,
balance: PropTypes.string,
conversionRate: PropTypes.number,
convertedCurrency: PropTypes.string,
gasTotal: PropTypes.string,
inError: PropTypes.bool,
primaryCurrency: PropTypes.string,
selectedToken: PropTypes.object,
setMaxModeTo: PropTypes.func,
tokenBalance: PropTypes.string,
updateSendAmountError: PropTypes.func,
updateSendAmount: PropTypes.func,
setMaxModeTo: PropTypes.func
updateSendAmountError: PropTypes.func,
}
validateAmount (amount) {
const {
amountConversionRate,
conversionRate,
balance,
conversionRate,
gasTotal,
primaryCurrency,
selectedToken,
@ -55,9 +59,8 @@ export default class SendAmountRow extends Component {
amount,
amountConversionRate,
convertedCurrency,
inError,
gasTotal,
maxModeOn,
inError,
primaryCurrency = 'ETH',
selectedToken,
} = this.props
@ -70,16 +73,16 @@ export default class SendAmountRow extends Component {
>
{!inError && gasTotal && <AmountMaxButton />}
<CurrencyDisplay
conversionRate={amountConversionRate}
convertedCurrency={convertedCurrency}
handleChange={newAmount => this.handleAmountChange(newAmount)}
inError={inError}
primaryCurrency={primaryCurrency}
convertedCurrency={convertedCurrency}
selectedToken={selectedToken}
value={amount || '0x0'}
conversionRate={amountConversionRate}
handleChange={newAmount => this.handleAmountChange(newAmount)}
/>
</SendRowWrapper>
);
)
}
}

View File

@ -1,24 +1,22 @@
import { connect } from 'react-redux'
import {
getSelectedToken,
getConvertedCurrency,
getSendAmount,
getGasTotal,
getSelectedBalance,
getTokenBalance,
getSendFromBalance,
getConversionRate,
getConvertedCurrency,
getGasTotal,
getSelectedToken,
getSendAmount,
getSendFromBalance,
getTokenBalance,
} from '../../send.selectors.js'
import {
getMaxModeOn,
sendAmountIsInError,
getPrimaryCurrency,
getAmountConversionRate,
getPrimaryCurrency,
sendAmountIsInError,
} from './send-amount-row.selectors.js'
import { getAmountErrorObject } from './send-amount-row.utils.js'
import {
updateSendAmount,
setMaxModeTo,
updateSendAmount,
updateSendErrors,
} from '../../../../actions'
import SendAmountRow from './send-amount-row.component'
@ -27,26 +25,25 @@ export default connect(mapStateToProps, mapDispatchToProps)(SendAmountRow)
function mapStateToProps (state) {
return {
selectedToken: getSelectedToken(state),
primaryCurrency: getPrimaryCurrency(state),
convertedCurrency: getConvertedCurrency(state),
amountConversionRate: getAmountConversionRate(state),
inError: sendAmountIsInError(state),
amount: getSendAmount(state),
maxModeOn: getMaxModeOn(state),
gasTotal: getGasTotal(state),
tokenBalance: getTokenBalance(state),
amountConversionRate: getAmountConversionRate(state),
balance: getSendFromBalance(state),
conversionRate: getConversionRate(state),
convertedCurrency: getConvertedCurrency(state),
gasTotal: getGasTotal(state),
inError: sendAmountIsInError(state),
primaryCurrency: getPrimaryCurrency(state),
selectedToken: getSelectedToken(state),
tokenBalance: getTokenBalance(state),
}
}
function mapDispatchToProps (dispatch) {
return {
setMaxModeTo: bool => dispatch(setMaxModeTo(bool)),
updateSendAmount: newAmount => dispatch(updateSendAmount(newAmount)),
updateSendAmountError: (amountDataObject) => {
dispatch(updateSendErrors(getAmountErrorObject(amountDataObject)))
},
updateSendAmount: newAmount => dispatch(updateSendAmount(newAmount)),
setMaxModeTo: bool => dispatch(setMaxModeTo(bool)),
}
}

View File

@ -5,10 +5,10 @@ import {
} from '../../send.selectors.js'
const selectors = {
getMaxModeOn,
sendAmountIsInError,
getPrimaryCurrency,
getAmountConversionRate,
getMaxModeOn,
getPrimaryCurrency,
sendAmountIsInError,
}
module.exports = selectors
@ -27,7 +27,7 @@ function getPrimaryCurrency (state) {
}
function getAmountConversionRate (state) {
return Boolean(getSelectedToken(state))
return getSelectedToken(state)
? getSelectedTokenToFiatRate(state)
: getConversionRate(state)
}

View File

@ -1,4 +1,3 @@
const { isValidAddress } = require('../../../../util')
const {
conversionGreaterThan,
} = require('../../../../conversion-util')
@ -9,31 +8,23 @@ const {
function getAmountErrorObject ({
amount,
balance,
amountConversionRate,
balance,
conversionRate,
gasTotal,
primaryCurrency,
selectedToken,
gasTotal,
tokenBalance,
}) {
console.log(`#& getAmountErrorObject amount`, amount);
console.log(`#& getAmountErrorObject balance`, balance);
console.log(`#& getAmountErrorObject amountConversionRate`, amountConversionRate);
console.log(`#& getAmountErrorObject conversionRate`, conversionRate);
console.log(`#& getAmountErrorObject primaryCurrency`, primaryCurrency);
console.log(`#& getAmountErrorObject selectedToken`, selectedToken);
console.log(`#& getAmountErrorObject gasTotal`, gasTotal);
console.log(`#& getAmountErrorObject tokenBalance`, tokenBalance);
let insufficientFunds = false
if (gasTotal && conversionRate) {
insufficientFunds = !isBalanceSufficient({
amount: selectedToken ? '0x0' : amount,
gasTotal,
balance,
primaryCurrency,
amountConversionRate,
balance,
conversionRate,
gasTotal,
primaryCurrency,
})
}
@ -66,5 +57,5 @@ function getAmountErrorObject ({
}
module.exports = {
getAmountErrorObject
getAmountErrorObject,
}

View File

@ -1,24 +1,23 @@
import React, { Component } from 'react'
import PageContainerContent from '../../page-container/page-container-content.component'
import SendFromRow from './send-from-row/send-from-row.container'
import SendToRow from './send-to-row/send-to-row.container'
import SendAmountRow from './send-amount-row/send-amount-row.container'
import SendFromRow from './send-from-row/send-from-row.container'
import SendGasRow from './send-gas-row/send-gas-row.container'
import SendToRow from './send-to-row/send-to-row.container'
export default class SendContent extends Component {
render () {
console.log('111222333444555666777888999')
return (
<PageContainerContent>
<div className='.send-v2__form'>
<div className=".send-v2__form">
<SendFromRow />
<SendToRow />
<SendAmountRow />
<SendGasRow />
</div>
</PageContainerContent>
);
)
}
}

View File

@ -26,25 +26,26 @@ export default class FromDropdown extends Component {
renderDropdown () {
const {
accounts,
selectedAccount,
closeDropdown,
onSelect,
selectedAccount,
} = this.props
return (<div>
<div
className='send-v2__from-dropdown__close-area'
className="send-v2__from-dropdown__close-area"
onClick={() => closeDropdown}
/>
<div className='send-v2__from-dropdown__list'>
{...accounts.map(account => <AccountListItem
className='account-list-item__dropdown'
<div className="send-v2__from-dropdown__list">
{...accounts.map((account, index) => <AccountListItem
account={account}
className="account-list-item__dropdown"
handleClick={() => {
onSelect(account)
closeDropdown()
}}
icon={this.getListItemIcon(account, selectedAccount.address)}
key={`from-dropdown-account-#${index}`}
/>)}
</div>
</div>)
@ -52,13 +53,12 @@ export default class FromDropdown extends Component {
render () {
const {
selectedAccount,
openDropdown,
dropdownOpen,
openDropdown,
selectedAccount,
} = this.props
console.log(`&*& openDropdown`, openDropdown);
console.log(`&*& dropdownOpen`, dropdownOpen);
return <div className='send-v2__from-dropdown'>
return <div className="send-v2__from-dropdown">
<AccountListItem
account={selectedAccount}
handleClick={openDropdown}

View File

@ -33,28 +33,27 @@ export default class SendFromRow extends Component {
render () {
const {
closeFromDropdown,
conversionRate,
from,
fromAccounts,
conversionRate,
fromDropdownOpen,
tokenContract,
openFromDropdown,
closeFromDropdown,
} = this.props
console.log(`$% SendFromRow fromAccounts`, fromAccounts);
return (
<SendRowWrapper label={`${this.context.t('from')}:`}>
<FromDropdown
dropdownOpen={fromDropdownOpen}
accounts={fromAccounts}
selectedAccount={from}
onSelect={newFrom => this.handleFromChange(newFrom)}
openDropdown={() => openFromDropdown()}
closeDropdown={() => closeFromDropdown()}
conversionRate={conversionRate}
dropdownOpen={fromDropdownOpen}
onSelect={newFrom => this.handleFromChange(newFrom)}
openDropdown={() => openFromDropdown()}
selectedAccount={from}
/>
</SendRowWrapper>
);
)
}
}

View File

@ -1,8 +1,8 @@
import { connect } from 'react-redux'
import {
accountsWithSendEtherInfoSelector,
getConversionRate,
getSelectedTokenContract,
accountsWithSendEtherInfoSelector,
getSendFromObject,
} from '../../send.selectors.js'
import {
@ -10,23 +10,22 @@ import {
} from './send-from-row.selectors.js'
import { calcTokenUpdateAmount } from './send-from-row.utils.js'
import {
updateSendTokenBalance,
updateSendFrom,
updateSendTokenBalance,
} from '../../../../actions'
import {
openFromDropdown,
closeFromDropdown,
openFromDropdown,
} from '../../../../ducks/send'
import SendFromRow from './send-from-row.component'
export default connect(mapStateToProps, mapDispatchToProps)(SendFromRow)
function mapStateToProps (state) {
console.log(`$% mapStateToProps accountsWithSendEtherInfoSelector`, accountsWithSendEtherInfoSelector);
return {
conversionRate: getConversionRate(state),
from: getSendFromObject(state),
fromAccounts: accountsWithSendEtherInfoSelector(state),
conversionRate: getConversionRate(state),
fromDropdownOpen: getFromDropdownOpen(state),
tokenContract: getSelectedTokenContract(state),
}
@ -34,14 +33,14 @@ function mapStateToProps (state) {
function mapDispatchToProps (dispatch) {
return {
closeFromDropdown: () => dispatch(closeFromDropdown()),
openFromDropdown: () => dispatch(openFromDropdown()),
updateSendFrom: newFrom => dispatch(updateSendFrom(newFrom)),
updateSendTokenBalance: (usersToken, selectedToken) => {
if (!usersToken) return
const tokenBalance = calcTokenUpdateAmount(selectedToken, selectedToken)
dispatch(updateSendTokenBalance(tokenBalance))
},
updateSendFrom: newFrom => dispatch(updateSendFrom(newFrom)),
openFromDropdown: () => dispatch(openFromDropdown()),
closeFromDropdown: () => dispatch(closeFromDropdown()),
}
}

View File

@ -8,5 +8,5 @@ function calcTokenUpdateAmount (usersToken, selectedToken) {
}
module.exports = {
calcTokenUpdateAmount
calcTokenUpdateAmount,
}

View File

@ -8,20 +8,23 @@ export default class SendGasRow extends Component {
static propTypes = {
closeFromDropdown: PropTypes.func,
conversionRate: PropTypes.number,
convertedCurrency: PropTypes.string,
from: PropTypes.string,
fromAccounts: PropTypes.array,
fromDropdownOpen: PropTypes.bool,
gasLoadingError: PropTypes.bool,
gasTotal: PropTypes.string,
openFromDropdown: PropTypes.func,
showCustomizeGasModal: PropTypes.bool,
tokenContract: PropTypes.object,
updateSendFrom: PropTypes.func,
updateSendTokenBalance: PropTypes.func,
gasLoadingError: PropTypes.bool,
};
async handleFromChange (newFrom) {
const {
updateSendFrom,
tokenContract,
updateSendFrom,
updateSendTokenBalance,
} = this.props
@ -36,22 +39,22 @@ export default class SendGasRow extends Component {
const {
conversionRate,
convertedCurrency,
showCustomizeGasModal,
gasTotal,
gasLoadingError,
gasTotal,
showCustomizeGasModal,
} = this.props
return (
<SendRowWrapper label={`${this.context.t('gasFee')}:`}>
<GasFeeDisplay
gasTotal={gasTotal}
conversionRate={conversionRate}
convertedCurrency={convertedCurrency}
onClick={() => showCustomizeGasModal()}
gasLoadingError={gasLoadingError}
gasTotal={gasTotal}
onClick={() => showCustomizeGasModal()}
/>
</SendRowWrapper>
);
)
}
}

View File

@ -14,9 +14,9 @@ export default class SendRowErrorMessage extends Component {
return (
errorMessage
? <div className='send-v2__error'>{this.context.t(errorMessage)}</div>
? <div className="send-v2__error">{this.context.t(errorMessage)}</div>
: null
);
)
}
}

View File

@ -5,22 +5,22 @@ import SendRowErrorMessage from './send-row-error-message/send-row-error-message
export default class SendRowWrapper extends Component {
static propTypes = {
label: PropTypes.string,
showError: PropTypes.bool,
children: PropTypes.node,
errorType: PropTypes.string,
label: PropTypes.string,
showError: PropTypes.bool,
};
render () {
const {
label,
errorType = '',
showError = false,
children,
errorType = '',
label,
showError = false,
} = this.props
let formField = Array.isArray(children) ? children[1] || children[0] : children
let customLabelContent = children.length === 1 ? children[0] : null
const formField = Array.isArray(children) ? children[1] || children[0] : children
const customLabelContent = children.length === 1 ? children[0] : null
return (
<div className="send-v2__form-row">
@ -33,7 +33,7 @@ export default class SendRowWrapper extends Component {
{formField}
</div>
</div>
);
)
}
}

View File

@ -6,15 +6,15 @@ import EnsInput from '../../../ens-input'
export default class SendToRow extends Component {
static propTypes = {
closeToDropdown: PropTypes.func,
inError: PropTypes.bool,
network: PropTypes.string,
openToDropdown: PropTypes.func,
to: PropTypes.string,
toAccounts: PropTypes.array,
toDropdownOpen: PropTypes.bool,
inError: PropTypes.bool,
updateSendTo: PropTypes.func,
updateSendToError: PropTypes.func,
openToDropdown: PropTypes.func,
closeToDropdown: PropTypes.func,
network: PropTypes.string,
};
handleToChange (to, nickname = '') {
@ -25,40 +25,35 @@ export default class SendToRow extends Component {
render () {
const {
from,
fromAccounts,
toAccounts,
conversionRate,
fromDropdownOpen,
tokenContract,
openToDropdown,
closeToDropdown,
network,
inError,
network,
openToDropdown,
to,
toAccounts,
toDropdownOpen,
} = this.props
return (
<SendRowWrapper
errorType={'to'}
label={`${this.context.t('to')}:`}
showError={inError}
errorType={'to'}
>
<EnsInput
name={'address'}
placeholder={this.context.t('recipientAddress')}
network={network}
to={to}
accounts={toAccounts}
dropdownOpen={toDropdownOpen}
openDropdown={() => openToDropdown()}
closeDropdown={() => closeToDropdown()}
onChange={(newTo, newNickname) => this.handleToChange(newTo, newNickname)}
dropdownOpen={toDropdownOpen}
inError={inError}
name={'address'}
network={network}
onChange={(newTo, newNickname) => this.handleToChange(newTo, newNickname)}
openDropdown={() => openToDropdown()}
placeholder={this.context.t('recipientAddress')}
to={to}
/>
</SendRowWrapper>
);
)
}
}

View File

@ -1,8 +1,7 @@
import { connect } from 'react-redux'
import {
getSendTo,
getToAccounts,
getCurrentNetwork,
getSendTo,
getSendToAccounts,
} from '../../send.selectors.js'
import {
@ -23,23 +22,22 @@ import SendToRow from './send-to-row.component'
export default connect(mapStateToProps, mapDispatchToProps)(SendToRow)
function mapStateToProps (state) {
updateSendTo
return {
inError: sendToIsInError(state),
network: getCurrentNetwork(state),
to: getSendTo(state),
toAccounts: getSendToAccounts(state),
toDropdownOpen: getToDropdownOpen(state),
inError: sendToIsInError(state),
network: getCurrentNetwork(state),
}
}
function mapDispatchToProps (dispatch) {
return {
closeToDropdown: () => dispatch(closeToDropdown()),
openToDropdown: () => dispatch(openToDropdown()),
updateSendTo: (to, nickname) => dispatch(updateSendTo(to, nickname)),
updateSendToError: (to) => {
dispatch(updateSendErrors(getToErrorObject(to)))
},
updateSendTo: (to, nickname) => dispatch(updateSendTo(to, nickname)),
openToDropdown: () => dispatch(openToDropdown()),
closeToDropdown: () => dispatch(closeToDropdown()),
}
}

View File

@ -13,5 +13,5 @@ function getToErrorObject (to) {
}
module.exports = {
getToErrorObject
getToErrorObject,
}

View File

@ -6,9 +6,10 @@ import { CONFIRM_TRANSACTION_ROUTE, DEFAULT_ROUTE } from '../../../routes'
export default class SendFooter extends Component {
static propTypes = {
addToAddressBook: PropTypes.func,
addToAddressBookIfNew: PropTypes.func,
amount: PropTypes.string,
clearSend: PropTypes.func,
disabled: PropTypes.bool,
editingTransactionId: PropTypes.string,
errors: PropTypes.object,
from: PropTypes.object,
@ -17,13 +18,12 @@ export default class SendFooter extends Component {
gasTotal: PropTypes.string,
history: PropTypes.object,
selectedToken: PropTypes.object,
signTokenTx: PropTypes.func,
signTx: PropTypes.func,
sign: PropTypes.func,
to: PropTypes.string,
toAccounts: PropTypes.array,
tokenBalance: PropTypes.string,
unapprovedTxs: PropTypes.object,
updateTx: PropTypes.func,
update: PropTypes.func,
};
onSubmit (event) {
@ -56,13 +56,13 @@ export default class SendFooter extends Component {
editingTransactionId
? update({
from,
to,
amount,
editingTransactionId,
from,
gas,
gasPrice,
selectedToken,
editingTransactionId,
to,
unapprovedTxs,
})
: sign({ selectedToken, to, amount, from, gas, gasPrice })
@ -83,7 +83,7 @@ export default class SendFooter extends Component {
onSubmit={e => this.onSubmit(e)}
disabled={disabled}
/>
);
)
}
}

View File

@ -27,31 +27,32 @@ import {
} from './send-footer.selectors'
import {
addressIsNew,
formShouldBeDisabled,
constructTxParams,
constructUpdatedTx,
formShouldBeDisabled,
} from './send-footer.utils'
export default connect(mapStateToProps, mapDispatchToProps)(SendFooter)
function mapStateToProps (state) {
return {
isToken: Boolean(getSelectedToken(state)),
inError: isSendFormInError(state),
amount: getSendAmount(state),
disabled: formShouldBeDisabled({
inError: isSendFormInError(state),
selectedToken: getSelectedToken(state),
tokenBalance: getTokenBalance(state),
gasTotal: getGasTotal(state),
}),
amount: getSendAmount(state),
editingTransactionId: getSendEditingTransactionId(state),
from: getSendFromObject(state),
gasLimit: getGasLimit(state),
gasPrice: getGasPrice(state),
inError: isSendFormInError(state),
isToken: Boolean(getSelectedToken(state)),
selectedToken: getSelectedToken(state),
to: getSendTo(state),
unapprovedTxs: getUnapprovedTxs(state),
toAccounts: getSendToAccounts(state),
unapprovedTxs: getUnapprovedTxs(state),
}
}
@ -102,6 +103,6 @@ function mapDispatchToProps (dispatch) {
// TODO: nickname, i.e. addToAddressBook(recipient, nickname)
dispatch(addToAddressBook(hexPrefixedAddress, nickname))
}
}
},
}
}

View File

@ -5,9 +5,9 @@ import PageContainerHeader from '../../page-container/page-container-header.comp
export default class SendHeader extends Component {
static propTypes = {
isToken: PropTypes.bool,
clearSend: PropTypes.func,
goHome: PropTypes.func,
isToken: PropTypes.bool,
};
render () {
@ -15,14 +15,14 @@ export default class SendHeader extends Component {
return (
<PageContainerHeader
title={isToken ? this.context.t('sendTokens') : this.context.t('sendETH')}
subtitle={this.context.t('onlySendToEtherAddress')}
onClose={() => {
clearSend()
goHome()
}}
subtitle={this.context.t('onlySendToEtherAddress')}
title={isToken ? this.context.t('sendTokens') : this.context.t('sendETH')}
/>
);
)
}
}

View File

@ -7,13 +7,13 @@ export default connect(mapStateToProps, mapDispatchToProps)(SendHeader)
function mapStateToProps (state) {
return {
isToken: Boolean(getSelectedToken(state))
isToken: Boolean(getSelectedToken(state)),
}
}
function mapDispatchToProps (dispatch) {
return {
goHome: () => dispatch(goHome()),
clearSend: () => dispatch(clearSend()),
goHome: () => dispatch(goHome()),
}
}

View File

@ -29,8 +29,8 @@ const selectors = {
getSendEditingTransactionId,
getSendErrors,
getSendFrom,
getSendFromObject,
getSendFromBalance,
getSendFromObject,
getSendMaxModeState,
getSendTo,
getSendToAccounts,
@ -43,169 +43,19 @@ const selectors = {
module.exports = selectors
function getSelectedAddress (state) {
const selectedAddress = state.metamask.selectedAddress || Object.keys(state.metamask.accounts)[0]
return selectedAddress
}
function getSelectedIdentity (state) {
const selectedAddress = getSelectedAddress(state)
const identities = state.metamask.identities
return identities[selectedAddress]
}
function getSelectedAccount (state) {
const accounts = state.metamask.accounts
const selectedAddress = getSelectedAddress(state)
return accounts[selectedAddress]
}
function getSelectedToken (state) {
const tokens = state.metamask.tokens || []
const selectedTokenAddress = state.metamask.selectedTokenAddress
const selectedToken = tokens.filter(({ address }) => address === selectedTokenAddress)[0]
const sendToken = state.metamask.send.token
return selectedToken || sendToken || null
}
function getSelectedTokenExchangeRate (state) {
const tokenExchangeRates = state.metamask.tokenExchangeRates
const selectedToken = getSelectedToken(state) || {}
const { symbol = '' } = selectedToken
const pair = `${symbol.toLowerCase()}_eth`
const { rate: tokenExchangeRate = 0 } = tokenExchangeRates[pair] || {}
return tokenExchangeRate
}
function getTokenExchangeRate (state, tokenSymbol) {
const pair = `${tokenSymbol.toLowerCase()}_eth`
const tokenExchangeRates = state.metamask.tokenExchangeRates
const { rate: tokenExchangeRate = 0 } = tokenExchangeRates[pair] || {}
return tokenExchangeRate
}
function getUnapprovedTxs (state) {
return state.metamask.unapprovedTxs
}
function getConversionRate (state) {
return state.metamask.conversionRate
}
function getConvertedCurrency (state) {
return state.metamask.currentCurrency
}
function getAddressBook (state) {
return state.metamask.addressBook
}
function accountsWithSendEtherInfoSelector (state) {
const {
accounts,
identities,
} = state.metamask
console.log(`accountsWithSendEtherInfoSelector accounts`, accounts);
console.log(`accountsWithSendEtherInfoSelector identities`, identities);
const accountsWithSendEtherInfo = Object.entries(accounts).map(([key, account]) => {
return Object.assign({}, account, identities[key])
})
console.log(`accountsWithSendEtherInfoSelector accountsWithSendEtherInfo`, accountsWithSendEtherInfo);
return accountsWithSendEtherInfo
}
function getCurrentAccountWithSendEtherInfo (state) {
const currentAddress = getSelectedAddress(state)
const accounts = accountsWithSendEtherInfoSelector(state)
return accounts.find(({ address }) => address === currentAddress)
}
function transactionsSelector (state) {
const { network, selectedTokenAddress } = state.metamask
const unapprovedMsgs = valuesFor(state.metamask.unapprovedMsgs)
const shapeShiftTxList = (network === '1') ? state.metamask.shapeShiftTxList : undefined
const transactions = state.metamask.selectedAddressTxList || []
const txsToRender = !shapeShiftTxList ? transactions.concat(unapprovedMsgs) : transactions.concat(unapprovedMsgs, shapeShiftTxList)
// console.log({txsToRender, selectedTokenAddress})
return selectedTokenAddress
? txsToRender
.filter(({ txParams }) => txParams && txParams.to === selectedTokenAddress)
.sort((a, b) => b.time - a.time)
: txsToRender
.sort((a, b) => b.time - a.time)
}
function getGasPrice (state) {
return state.metamask.send.gasPrice
}
function getGasTotal (state) {
return state.metamask.send.gasTotal
}
function getGasLimit (state) {
return state.metamask.send.gasLimit
}
function getForceGasMin (state) {
return state.metamask.send.forceGasMin
}
function getSendFrom (state) {
return state.metamask.send.from
}
function getSendFromObject (state) {
return getSendFrom(state) || getCurrentAccountWithSendEtherInfo(state)
}
function getSendFromBalance (state) {
const from = getSendFrom(state) || getSelectedAccount(state)
return from.balance
}
function getSendAmount (state) {
return state.metamask.send.amount
}
function getSendMaxModeState (state) {
return state.metamask.send.maxModeOn
}
function getCurrentCurrency (state) {
return state.metamask.currentCurrency
}
function getSelectedTokenToFiatRate (state) {
const selectedTokenExchangeRate = getSelectedTokenExchangeRate(state)
const conversionRate = getConversionRate(state)
const tokenToFiatRate = multiplyCurrencies(
conversionRate,
selectedTokenExchangeRate,
{ toNumericBase: 'dec' }
)
return tokenToFiatRate
}
function getSelectedTokenContract (state) {
const selectedToken = getSelectedToken(state)
return selectedToken
? global.eth.contract(abi).at(selectedToken.address)
: null
}
function autoAddToBetaUI (state) {
const autoAddTransactionThreshold = 12
const autoAddAccountsThreshold = 2
@ -223,11 +73,118 @@ function autoAddToBetaUI (state) {
return userIsNotInBeta && userPassesThreshold
}
function getAddressBook (state) {
return state.metamask.addressBook
}
function getConversionRate (state) {
return state.metamask.conversionRate
}
function getConvertedCurrency (state) {
return state.metamask.currentCurrency
}
function getCurrentAccountWithSendEtherInfo (state) {
const currentAddress = getSelectedAddress(state)
const accounts = accountsWithSendEtherInfoSelector(state)
return accounts.find(({ address }) => address === currentAddress)
}
function getCurrentCurrency (state) {
return state.metamask.currentCurrency
}
function getCurrentNetwork (state) {
return state.metamask.network
}
function getCurrentViewContext (state) {
const { currentView = {} } = state.appState
return currentView.context
}
function getForceGasMin (state) {
return state.metamask.send.forceGasMin
}
function getGasPrice (state) {
return state.metamask.send.gasPrice
}
function getGasLimit (state) {
return state.metamask.send.gasLimit
}
function getGasTotal (state) {
return state.metamask.send.gasTotal
}
function getSelectedAccount (state) {
const accounts = state.metamask.accounts
const selectedAddress = getSelectedAddress(state)
return accounts[selectedAddress]
}
function getSelectedAddress (state) {
const selectedAddress = state.metamask.selectedAddress || Object.keys(state.metamask.accounts)[0]
return selectedAddress
}
function getSelectedIdentity (state) {
const selectedAddress = getSelectedAddress(state)
const identities = state.metamask.identities
return identities[selectedAddress]
}
function getSelectedToken (state) {
const tokens = state.metamask.tokens || []
const selectedTokenAddress = state.metamask.selectedTokenAddress
const selectedToken = tokens.filter(({ address }) => address === selectedTokenAddress)[0]
const sendToken = state.metamask.send.token
return selectedToken || sendToken || null
}
function getSelectedTokenContract (state) {
const selectedToken = getSelectedToken(state)
return selectedToken
? global.eth.contract(abi).at(selectedToken.address)
: null
}
function getSelectedTokenExchangeRate (state) {
const tokenExchangeRates = state.metamask.tokenExchangeRates
const selectedToken = getSelectedToken(state) || {}
const { symbol = '' } = selectedToken
const pair = `${symbol.toLowerCase()}_eth`
const { rate: tokenExchangeRate = 0 } = tokenExchangeRates[pair] || {}
return tokenExchangeRate
}
function getSelectedTokenToFiatRate (state) {
const selectedTokenExchangeRate = getSelectedTokenExchangeRate(state)
const conversionRate = getConversionRate(state)
const tokenToFiatRate = multiplyCurrencies(
conversionRate,
selectedTokenExchangeRate,
{ toNumericBase: 'dec' }
)
return tokenToFiatRate
}
function getSendAmount (state) {
return state.metamask.send.amount
}
function getSendEditingTransactionId (state) {
return state.metamask.send.editingTransactionId
}
@ -236,12 +193,25 @@ function getSendErrors (state) {
return state.metamask.send.errors
}
function getSendTo (state) {
return state.metamask.send.to
function getSendFrom (state) {
return state.metamask.send.from
}
function getTokenBalance (state) {
return state.metamask.send.tokenBalance
function getSendFromBalance (state) {
const from = getSendFrom(state) || getSelectedAccount(state)
return from.balance
}
function getSendFromObject (state) {
return getSendFrom(state) || getCurrentAccountWithSendEtherInfo(state)
}
function getSendMaxModeState (state) {
return state.metamask.send.maxModeOn
}
function getSendTo (state) {
return state.metamask.send.to
}
function getSendToAccounts (state) {
@ -252,11 +222,38 @@ function getSendToAccounts (state) {
return Object.entries(allAccounts).map(([key, account]) => account)
}
function getCurrentNetwork (state) {
return state.metamask.network
function getTokenBalance (state) {
return state.metamask.send.tokenBalance
}
function getTokenExchangeRate (state, tokenSymbol) {
const pair = `${tokenSymbol.toLowerCase()}_eth`
const tokenExchangeRates = state.metamask.tokenExchangeRates
const { rate: tokenExchangeRate = 0 } = tokenExchangeRates[pair] || {}
return tokenExchangeRate
}
function getUnapprovedTxs (state) {
return state.metamask.unapprovedTxs
}
function isSendFormInError (state) {
const { amount, to } = getSendErrors(state)
return Boolean(amount || toError !== null)
return Boolean(amount || to !== null)
}
function transactionsSelector (state) {
const { network, selectedTokenAddress } = state.metamask
const unapprovedMsgs = valuesFor(state.metamask.unapprovedMsgs)
const shapeShiftTxList = (network === '1') ? state.metamask.shapeShiftTxList : undefined
const transactions = state.metamask.selectedAddressTxList || []
const txsToRender = !shapeShiftTxList ? transactions.concat(unapprovedMsgs) : transactions.concat(unapprovedMsgs, shapeShiftTxList)
return selectedTokenAddress
? txsToRender
.filter(({ txParams }) => txParams && txParams.to === selectedTokenAddress)
.sort((a, b) => b.time - a.time)
: txsToRender
.sort((a, b) => b.time - a.time)
}

View File

@ -8,13 +8,21 @@ const {
calcTokenAmount,
} = require('../../token-util')
function getGasTotal (gasLimit, gasPrice) {
return multiplyCurrencies(gasLimit, gasPrice, {
toNumericBase: 'hex',
multiplicandBase: 16,
multiplierBase: 16,
})
}
function isBalanceSufficient ({
amount = '0x0',
gasTotal = '0x0',
balance,
primaryCurrency,
amountConversionRate,
balance,
conversionRate,
gasTotal = '0x0',
primaryCurrency,
}) {
const totalAmount = addCurrencies(amount, gasTotal, {
aBase: 16,
@ -63,14 +71,6 @@ function isTokenBalanceSufficient ({
return tokenBalanceIsSufficient
}
function getGasTotal (gasLimit, gasPrice) {
return multiplyCurrencies(gasLimit, gasPrice, {
toNumericBase: 'hex',
multiplicandBase: 16,
multiplierBase: 16,
})
}
module.exports = {
getGasTotal,
isBalanceSufficient,

View File

@ -1,10 +1,10 @@
import extend from 'xtend'
// Actions
const OPEN_FROM_DROPDOWN = 'metamask/send/OPEN_FROM_DROPDOWN';
const CLOSE_FROM_DROPDOWN = 'metamask/send/CLOSE_FROM_DROPDOWN';
const OPEN_TO_DROPDOWN = 'metamask/send/OPEN_TO_DROPDOWN';
const CLOSE_TO_DROPDOWN = 'metamask/send/CLOSE_TO_DROPDOWN';
const OPEN_FROM_DROPDOWN = 'metamask/send/OPEN_FROM_DROPDOWN'
const CLOSE_FROM_DROPDOWN = 'metamask/send/CLOSE_FROM_DROPDOWN'
const OPEN_TO_DROPDOWN = 'metamask/send/OPEN_TO_DROPDOWN'
const CLOSE_TO_DROPDOWN = 'metamask/send/CLOSE_TO_DROPDOWN'
// TODO: determine if this approach to initState is consistent with conventional ducks pattern
const initState = {
@ -39,17 +39,17 @@ export default function reducer({ send: sendState = initState }, action = {}) {
// Action Creators
export function openFromDropdown () {
return { type: OPEN_FROM_DROPDOWN };
return { type: OPEN_FROM_DROPDOWN }
}
export function closeFromDropdown () {
return { type: CLOSE_FROM_DROPDOWN };
return { type: CLOSE_FROM_DROPDOWN }
}
export function openToDropdown () {
return { type: OPEN_TO_DROPDOWN };
return { type: OPEN_TO_DROPDOWN }
}
export function closeToDropdown () {
return { type: CLOSE_TO_DROPDOWN };
return { type: CLOSE_TO_DROPDOWN }
}

View File

@ -3,23 +3,8 @@ const PropTypes = require('prop-types')
const PersistentForm = require('../lib/persistent-form')
const h = require('react-hyperscript')
const ethAbi = require('ethereumjs-abi')
const ethUtil = require('ethereumjs-util')
const FromDropdown = require('./components/send/from-dropdown')
const EnsInput = require('./components/ens-input')
const CurrencyDisplay = require('./components/send/currency-display')
const MemoTextArea = require('./components/send/memo-textarea')
const GasFeeDisplay = require('./components/send/gas-fee-display-v2')
const {
TOKEN_TRANSFER_FUNCTION_SIGNATURE,
} = require('./components/send/send-constants')
const {
multiplyCurrencies,
conversionGreaterThan,
subtractCurrencies,
} = require('./conversion-util')
const {
calcTokenAmount,
@ -29,8 +14,6 @@ const {
isTokenBalanceSufficient,
getGasTotal,
} = require('./components/send/send-utils')
const { isValidAddress } = require('./util')
const { CONFIRM_TRANSACTION_ROUTE, DEFAULT_ROUTE } = require('./routes')
import PageContainer from './components/page-container/page-container.component'
import SendHeader from './components/send_/send-header/send-header.container'