diff options
first commit
Diffstat (limited to 'ui/app/components/send_')
83 files changed, 654 insertions, 0 deletions
diff --git a/ui/app/components/send_/README.md b/ui/app/components/send_/README.md new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/README.md diff --git a/ui/app/components/send_/send-content/send-amount-row/README.md b/ui/app/components/send_/send-content/send-amount-row/README.md new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-content/send-amount-row/README.md diff --git a/ui/app/components/send_/send-content/send-amount-row/amount-max-button/amount-max-button.component.js b/ui/app/components/send_/send-content/send-amount-row/amount-max-button/amount-max-button.component.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-content/send-amount-row/amount-max-button/amount-max-button.component.js diff --git a/ui/app/components/send_/send-content/send-amount-row/amount-max-button/amount-max-button.container.js b/ui/app/components/send_/send-content/send-amount-row/amount-max-button/amount-max-button.container.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-content/send-amount-row/amount-max-button/amount-max-button.container.js diff --git a/ui/app/components/send_/send-content/send-amount-row/amount-max-button/amount-max-button.selectors.js b/ui/app/components/send_/send-content/send-amount-row/amount-max-button/amount-max-button.selectors.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-content/send-amount-row/amount-max-button/amount-max-button.selectors.js diff --git a/ui/app/components/send_/send-content/send-amount-row/amount-max-button/amount-max-button.utils.js b/ui/app/components/send_/send-content/send-amount-row/amount-max-button/amount-max-button.utils.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-content/send-amount-row/amount-max-button/amount-max-button.utils.js diff --git a/ui/app/components/send_/send-content/send-amount-row/amount-max-button/tests/amount-max-button-component.test.js b/ui/app/components/send_/send-content/send-amount-row/amount-max-button/tests/amount-max-button-component.test.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-content/send-amount-row/amount-max-button/tests/amount-max-button-component.test.js diff --git a/ui/app/components/send_/send-content/send-amount-row/amount-max-button/tests/amount-max-button-container.test.js b/ui/app/components/send_/send-content/send-amount-row/amount-max-button/tests/amount-max-button-container.test.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-content/send-amount-row/amount-max-button/tests/amount-max-button-container.test.js diff --git a/ui/app/components/send_/send-content/send-amount-row/amount-max-button/tests/amount-max-button-selectors.test.js b/ui/app/components/send_/send-content/send-amount-row/amount-max-button/tests/amount-max-button-selectors.test.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-content/send-amount-row/amount-max-button/tests/amount-max-button-selectors.test.js diff --git a/ui/app/components/send_/send-content/send-amount-row/amount-max-button/tests/amount-max-button-utils.test.js b/ui/app/components/send_/send-content/send-amount-row/amount-max-button/tests/amount-max-button-utils.test.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-content/send-amount-row/amount-max-button/tests/amount-max-button-utils.test.js diff --git a/ui/app/components/send_/send-content/send-amount-row/send-amount-row.component.js b/ui/app/components/send_/send-content/send-amount-row/send-amount-row.component.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-content/send-amount-row/send-amount-row.component.js diff --git a/ui/app/components/send_/send-content/send-amount-row/send-amount-row.container.js b/ui/app/components/send_/send-content/send-amount-row/send-amount-row.container.js new file mode 100644 index 000000000..6ae80e7f2 --- /dev/null +++ b/ui/app/components/send_/send-content/send-amount-row/send-amount-row.container.js @@ -0,0 +1,48 @@ +import { + getSelectedToken, + getPrimaryCurrency, + getAmountConversionRate, + getConvertedCurrency, + getSendAmount, + getGasTotal, + getSelectedBalance, + getTokenBalance, +} from '../../send.selectors.js' +import { + getMaxModeOn, + getSendAmountError, +} from './send-amount-row.selectors.js' +import { getAmountErrorObject } from './send-to-row.utils.js' +import { + updateSendErrors, + updateSendTo, +} from '../../../actions' +import { + openToDropdown, + closeToDropdown, +} from '../../../ducks/send' +import SendToRow from './send-to-row.component' + +export default connect(mapStateToProps, mapDispatchToProps)(SendToRow) + +function mapStateToProps (state) { +updateSendTo +return { + to: getSendTo(state), + toAccounts: getSendToAccounts(state), + toDropdownOpen: getToDropdownOpen(state), + inError: sendToIsInError(state), + network: getCurrentNetwork(state), +} +} + +function mapDispatchToProps (dispatch) { +return { + updateSendToError: (to) => { + dispatch(updateSendErrors(getToErrorObject(to))) + }, + updateSendTo: (to, nickname) => dispatch(updateSendTo(to, nickname)), + openToDropdown: () => dispatch(()), + closeToDropdown: () => dispatch(()), +} +}
\ No newline at end of file diff --git a/ui/app/components/send_/send-content/send-amount-row/send-amount-row.scss b/ui/app/components/send_/send-content/send-amount-row/send-amount-row.scss new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-content/send-amount-row/send-amount-row.scss diff --git a/ui/app/components/send_/send-content/send-amount-row/send-amount-row.selectors.js b/ui/app/components/send_/send-content/send-amount-row/send-amount-row.selectors.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-content/send-amount-row/send-amount-row.selectors.js diff --git a/ui/app/components/send_/send-content/send-amount-row/send-amount-row.utils.js b/ui/app/components/send_/send-content/send-amount-row/send-amount-row.utils.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-content/send-amount-row/send-amount-row.utils.js diff --git a/ui/app/components/send_/send-content/send-amount-row/tests/send-amount-row-component.test.js b/ui/app/components/send_/send-content/send-amount-row/tests/send-amount-row-component.test.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-content/send-amount-row/tests/send-amount-row-component.test.js diff --git a/ui/app/components/send_/send-content/send-amount-row/tests/send-amount-row-container.test.js b/ui/app/components/send_/send-content/send-amount-row/tests/send-amount-row-container.test.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-content/send-amount-row/tests/send-amount-row-container.test.js diff --git a/ui/app/components/send_/send-content/send-amount-row/tests/send-amount-row-selectors.test.js b/ui/app/components/send_/send-content/send-amount-row/tests/send-amount-row-selectors.test.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-content/send-amount-row/tests/send-amount-row-selectors.test.js diff --git a/ui/app/components/send_/send-content/send-amount-row/tests/send-amount-row-utils.test.js b/ui/app/components/send_/send-content/send-amount-row/tests/send-amount-row-utils.test.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-content/send-amount-row/tests/send-amount-row-utils.test.js diff --git a/ui/app/components/send_/send-content/send-content-README.md b/ui/app/components/send_/send-content/send-content-README.md new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-content/send-content-README.md diff --git a/ui/app/components/send_/send-content/send-content.component.js b/ui/app/components/send_/send-content/send-content.component.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-content/send-content.component.js diff --git a/ui/app/components/send_/send-content/send-content.scss b/ui/app/components/send_/send-content/send-content.scss new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-content/send-content.scss diff --git a/ui/app/components/send_/send-content/send-from-row/from-dropdown/from-dropdown-README.md b/ui/app/components/send_/send-content/send-from-row/from-dropdown/from-dropdown-README.md new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-content/send-from-row/from-dropdown/from-dropdown-README.md diff --git a/ui/app/components/send_/send-content/send-from-row/from-dropdown/from-dropdown.component.js b/ui/app/components/send_/send-content/send-from-row/from-dropdown/from-dropdown.component.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-content/send-from-row/from-dropdown/from-dropdown.component.js diff --git a/ui/app/components/send_/send-content/send-from-row/from-dropdown/from-dropdown.scss b/ui/app/components/send_/send-content/send-from-row/from-dropdown/from-dropdown.scss new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-content/send-from-row/from-dropdown/from-dropdown.scss diff --git a/ui/app/components/send_/send-content/send-from-row/from-dropdown/tests/from-dropdown-component.test.js b/ui/app/components/send_/send-content/send-from-row/from-dropdown/tests/from-dropdown-component.test.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-content/send-from-row/from-dropdown/tests/from-dropdown-component.test.js diff --git a/ui/app/components/send_/send-content/send-from-row/send-from-row-README.md b/ui/app/components/send_/send-content/send-from-row/send-from-row-README.md new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-content/send-from-row/send-from-row-README.md diff --git a/ui/app/components/send_/send-content/send-from-row/send-from-row.component.js b/ui/app/components/send_/send-content/send-from-row/send-from-row.component.js new file mode 100644 index 000000000..7582cb2e6 --- /dev/null +++ b/ui/app/components/send_/send-content/send-from-row/send-from-row.component.js @@ -0,0 +1,64 @@ +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import SendRowWrapper from '../../../send/from-dropdown' +import FromDropdown from '' + +export default class SendFromRow extends Component { + + static propTypes = { + closeFromDropdown: PropTypes.func, + conversionRate: PropTypes.string, + from: PropTypes.string, + fromAccounts: PropTypes.array, + fromDropdownOpen: PropTypes.bool, + openFromDropdown: PropTypes.func, + tokenContract: PropTypes.object, + updateSendFrom: PropTypes.func, + updateSendTokenBalance: PropTypes.func, + }; + + async handleFromChange (newFrom) { + const { + updateSendFrom, + tokenContract, + updateSendTokenBalance, + } = this.props + + if (tokenContract) { + const usersToken = await tokenContract.balanceOf(newFrom.address) + updateSendTokenBalance(usersToken) + } + updateSendFrom(newFrom) + } + + render () { + const { + from, + fromAccounts, + conversionRate, + fromDropdownOpen, + tokenContract, + openFromDropdown, + closeFromDropdown, + } = this.props + + 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} + /> + </SendRowWrapper> + ); + } + +} + +SendFromRow.contextTypes = { + t: PropTypes.func, +} diff --git a/ui/app/components/send_/send-content/send-from-row/send-from-row.container.js b/ui/app/components/send_/send-content/send-from-row/send-from-row.container.js new file mode 100644 index 000000000..2ff3f0ccd --- /dev/null +++ b/ui/app/components/send_/send-content/send-from-row/send-from-row.container.js @@ -0,0 +1,44 @@ +import { + getSendFrom, + conversionRateSelector, + getSelectedTokenContract, + getCurrentAccountWithSendEtherInfo, + accountsWithSendEtherInfoSelector, +} from '../../send.selectors.js' +import { getFromDropdownOpen } from './send-from-row.selectors.js' +import { calcTokenUpdateAmount } from './send-from-row.utils.js' +import { + updateSendTokenBalance, + updateSendFrom, +} from '../../../actions' +import { + openFromDropdown, + closeFromDropdown, +} from '../../../ducks/send' +import SendFromRow from './send-from-row.component' + +export default connect(mapStateToProps, mapDispatchToProps)(SendFromRow) + +function mapStateToProps (state) { + return { + from: getSendFrom(state) || getCurrentAccountWithSendEtherInfo(state), + fromAccounts: accountsWithSendEtherInfoSelector(state), + conversionRate: conversionRateSelector(state), + fromDropdownOpen: getFromDropdownOpen(state), + tokenContract: getSelectedTokenContract(state), + } +} + +function mapDispatchToProps (dispatch) { + return { + updateSendTokenBalance: (usersToken, selectedToken) => { + if (!usersToken) return + + const tokenBalance = calcTokenUpdateAmount(selectedToken, selectedToken) + dispatch(updateSendTokenBalance(tokenBalance)) + }, + updateSendFrom: newFrom => dispatch(updateSendFrom(newFrom)), + openFromDropdown: () => dispatch(()), + closeFromDropdown: () => dispatch(()), + } +} diff --git a/ui/app/components/send_/send-content/send-from-row/send-from-row.selectors.js b/ui/app/components/send_/send-content/send-from-row/send-from-row.selectors.js new file mode 100644 index 000000000..03ef4806b --- /dev/null +++ b/ui/app/components/send_/send-content/send-from-row/send-from-row.selectors.js @@ -0,0 +1,9 @@ +const selectors = { + getFromDropdownOpen, +} + +module.exports = selectors + +function getFromDropdownOpen (state) { + return state.send.fromDropdownOpen +} diff --git a/ui/app/components/send_/send-content/send-from-row/send-from-row.utils.js b/ui/app/components/send_/send-content/send-from-row/send-from-row.utils.js new file mode 100644 index 000000000..2be25816f --- /dev/null +++ b/ui/app/components/send_/send-content/send-from-row/send-from-row.utils.js @@ -0,0 +1,12 @@ +const { + calcTokenAmount, +} = require('../../token-util') + +function calcTokenUpdateAmount (usersToken, selectedToken) { + const { decimals } = selectedToken || {} + return calcTokenAmount(usersToken.balance.toString(), decimals) +} + +module.exports = { + calcTokenUpdateAmount +} diff --git a/ui/app/components/send_/send-content/send-from-row/tests/send-from-row-component.test.js b/ui/app/components/send_/send-content/send-from-row/tests/send-from-row-component.test.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-content/send-from-row/tests/send-from-row-component.test.js diff --git a/ui/app/components/send_/send-content/send-from-row/tests/send-from-row-container.test.js b/ui/app/components/send_/send-content/send-from-row/tests/send-from-row-container.test.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-content/send-from-row/tests/send-from-row-container.test.js diff --git a/ui/app/components/send_/send-content/send-from-row/tests/send-from-row-selectors.test.js b/ui/app/components/send_/send-content/send-from-row/tests/send-from-row-selectors.test.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-content/send-from-row/tests/send-from-row-selectors.test.js diff --git a/ui/app/components/send_/send-content/send-gas-row/README.md b/ui/app/components/send_/send-content/send-gas-row/README.md new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-content/send-gas-row/README.md diff --git a/ui/app/components/send_/send-content/send-gas-row/send-gas-row.component.js b/ui/app/components/send_/send-content/send-gas-row/send-gas-row.component.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-content/send-gas-row/send-gas-row.component.js diff --git a/ui/app/components/send_/send-content/send-gas-row/send-gas-row.container.js b/ui/app/components/send_/send-content/send-gas-row/send-gas-row.container.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-content/send-gas-row/send-gas-row.container.js diff --git a/ui/app/components/send_/send-content/send-gas-row/send-gas-row.scss b/ui/app/components/send_/send-content/send-gas-row/send-gas-row.scss new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-content/send-gas-row/send-gas-row.scss diff --git a/ui/app/components/send_/send-content/send-gas-row/send-gas-row.selectors.js b/ui/app/components/send_/send-content/send-gas-row/send-gas-row.selectors.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-content/send-gas-row/send-gas-row.selectors.js diff --git a/ui/app/components/send_/send-content/send-gas-row/tests/send-gas-row-component.test.js b/ui/app/components/send_/send-content/send-gas-row/tests/send-gas-row-component.test.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-content/send-gas-row/tests/send-gas-row-component.test.js diff --git a/ui/app/components/send_/send-content/send-gas-row/tests/send-gas-row-container.test.js b/ui/app/components/send_/send-content/send-gas-row/tests/send-gas-row-container.test.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-content/send-gas-row/tests/send-gas-row-container.test.js diff --git a/ui/app/components/send_/send-content/send-gas-row/tests/send-gas-row-selectors.test.js b/ui/app/components/send_/send-content/send-gas-row/tests/send-gas-row-selectors.test.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-content/send-gas-row/tests/send-gas-row-selectors.test.js diff --git a/ui/app/components/send_/send-content/send-row-wrapper/send-row-error-message/send-row-error-message-README.md b/ui/app/components/send_/send-content/send-row-wrapper/send-row-error-message/send-row-error-message-README.md new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-content/send-row-wrapper/send-row-error-message/send-row-error-message-README.md diff --git a/ui/app/components/send_/send-content/send-row-wrapper/send-row-error-message/send-row-error-message.component.js b/ui/app/components/send_/send-content/send-row-wrapper/send-row-error-message/send-row-error-message.component.js new file mode 100644 index 000000000..08f830cc5 --- /dev/null +++ b/ui/app/components/send_/send-content/send-row-wrapper/send-row-error-message/send-row-error-message.component.js @@ -0,0 +1,23 @@ +export default class SendRowErrorMessage extends Component { + + static propTypes = { + errors: PropTypes.object, + errorType: PropTypes.string, + }; + + render () { + const { errors, errorType } = this.props + const errorMessage = errors[errorType] + + return ( + errorMessage + ? <div className='send-v2__error'>{errorMessage}</div> + : null + ); + } + +} + +SendRowErrorMessage.contextTypes = { + t: PropTypes.func, +}
\ No newline at end of file diff --git a/ui/app/components/send_/send-content/send-row-wrapper/send-row-error-message/send-row-error-message.container.js b/ui/app/components/send_/send-content/send-row-wrapper/send-row-error-message/send-row-error-message.container.js new file mode 100644 index 000000000..2278dbe63 --- /dev/null +++ b/ui/app/components/send_/send-content/send-row-wrapper/send-row-error-message/send-row-error-message.container.js @@ -0,0 +1,11 @@ +import { getSendErrors } from '../../../send.selectors' +import SendRowErrorMessage from './send-row-error-message.component' + +export default connect(mapStateToProps)(SendRowErrorMessage) + +function mapStateToProps (state, ownProps) { + return { + errors: getSendErrors(state), + errorType: ownProps.errorType, + } +}
\ No newline at end of file diff --git a/ui/app/components/send_/send-content/send-row-wrapper/send-row-error-message/send-row-error-message.scss b/ui/app/components/send_/send-content/send-row-wrapper/send-row-error-message/send-row-error-message.scss new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-content/send-row-wrapper/send-row-error-message/send-row-error-message.scss diff --git a/ui/app/components/send_/send-content/send-row-wrapper/send-row-wrapper-README.md b/ui/app/components/send_/send-content/send-row-wrapper/send-row-wrapper-README.md new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-content/send-row-wrapper/send-row-wrapper-README.md diff --git a/ui/app/components/send_/send-content/send-row-wrapper/send-row-wrapper.component.js b/ui/app/components/send_/send-content/send-row-wrapper/send-row-wrapper.component.js new file mode 100644 index 000000000..a1ac591b9 --- /dev/null +++ b/ui/app/components/send_/send-content/send-row-wrapper/send-row-wrapper.component.js @@ -0,0 +1,39 @@ +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import SendRowErrorMessage from './send-row-error-message/send-row-error-message.container' + +export default class SendRowWrapper extends Component { + + static propTypes = { + label: PropTypes.string, + showError: PropTypes.bool, + children: PropTypes.node, + errorType: PropTypes.string, + }; + + render () { + const { + label, + errorType = '', + showError = false, + children, + } = this.props + + return ( + <div className="send-v2__form-row"> + <div className="send-v2__form-label"> + {label} + (showError && <SendRowErrorMessage errorType={errorType}/>) + </div> + <div className="send-v2__form-field"> + {children} + </div> + </div> + ); + } + +} + +SendRowWrapper.contextTypes = { + t: PropTypes.func, +} diff --git a/ui/app/components/send_/send-content/send-row-wrapper/send-row-wrapper.scss b/ui/app/components/send_/send-content/send-row-wrapper/send-row-wrapper.scss new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-content/send-row-wrapper/send-row-wrapper.scss diff --git a/ui/app/components/send_/send-content/send-row-wrapper/tests/send-row-wrapper-component.test.js b/ui/app/components/send_/send-content/send-row-wrapper/tests/send-row-wrapper-component.test.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-content/send-row-wrapper/tests/send-row-wrapper-component.test.js diff --git a/ui/app/components/send_/send-content/send-to-row/send-to-row-README.md b/ui/app/components/send_/send-content/send-to-row/send-to-row-README.md new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-content/send-to-row/send-to-row-README.md diff --git a/ui/app/components/send_/send-content/send-to-row/send-to-row.component.js b/ui/app/components/send_/send-content/send-to-row/send-to-row.component.js new file mode 100644 index 000000000..abcb54efc --- /dev/null +++ b/ui/app/components/send_/send-content/send-to-row/send-to-row.component.js @@ -0,0 +1,62 @@ +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import SendRowWrapper from '../../../send/from-dropdown' +import ToDropdown from '../../../ens-input' + +export default class SendToRow extends Component { + + static propTypes = { + 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.number, + }; + + handleToChange (to, nickname = '') { + const { updateSendTo, updateSendToError } = this.props + updateSendTo(to, nickname) + updateSendErrors(to) + } + + render () { + const { + from, + fromAccounts, + conversionRate, + fromDropdownOpen, + tokenContract, + openToDropdown, + closeToDropdown, + network, + inError, + } = this.props + + return ( + <SendRowWrapper label={`${this.context.t('to')}:`}> + <EnsInput + name={'address'} + placeholder={this.context.t('recipient Address')} + network={network}, + to={to}, + accounts={toAccounts} + dropdownOpen={toDropdownOpen} + openDropdown={() => openToDropdown()} + closeDropdown={() => closeToDropdown()} + onChange={this.handleToChange} + inError={inError} + /> + </SendRowWrapper> + ); + } + +} + +SendToRow.contextTypes = { + t: PropTypes.func, +} + diff --git a/ui/app/components/send_/send-content/send-to-row/send-to-row.container.js b/ui/app/components/send_/send-content/send-to-row/send-to-row.container.js new file mode 100644 index 000000000..1c446c168 --- /dev/null +++ b/ui/app/components/send_/send-content/send-to-row/send-to-row.container.js @@ -0,0 +1,43 @@ +import { + getSendTo, + getToAccounts, + getCurrentNetwork, +} from '../../send.selectors.js' +import { + getToDropdownOpen, + sendToIsInError, +} from './send-to-row.selectors.js' +import { getToErrorObject } from './send-to-row.utils.js' +import { + updateSendErrors, + updateSendTo, +} from '../../../actions' +import { + openToDropdown, + closeToDropdown, +} from '../../../ducks/send' +import SendToRow from './send-to-row.component' + +export default connect(mapStateToProps, mapDispatchToProps)(SendToRow) + +function mapStateToProps (state) { + updateSendTo + return { + to: getSendTo(state), + toAccounts: getSendToAccounts(state), + toDropdownOpen: getToDropdownOpen(state), + inError: sendToIsInError(state), + network: getCurrentNetwork(state), + } +} + +function mapDispatchToProps (dispatch) { + return { + updateSendToError: (to) => { + dispatch(updateSendErrors(getToErrorObject(to))) + }, + updateSendTo: (to, nickname) => dispatch(updateSendTo(to, nickname)), + openToDropdown: () => dispatch(()), + closeToDropdown: () => dispatch(()), + } +}
\ No newline at end of file diff --git a/ui/app/components/send_/send-content/send-to-row/send-to-row.selectors.js b/ui/app/components/send_/send-content/send-to-row/send-to-row.selectors.js new file mode 100644 index 000000000..05bb65fa3 --- /dev/null +++ b/ui/app/components/send_/send-content/send-to-row/send-to-row.selectors.js @@ -0,0 +1,14 @@ +const selectors = { + getToDropdownOpen, + sendToIsInError, +} + +module.exports = selectors + +function getToDropdownOpen (state) { + return state.send.toDropdownOpen +} + +function sendToIsInError (state) { + return Boolean(state.metamask.send.to) +} diff --git a/ui/app/components/send_/send-content/send-to-row/send-to-row.utils.js b/ui/app/components/send_/send-content/send-to-row/send-to-row.utils.js new file mode 100644 index 000000000..52bfde009 --- /dev/null +++ b/ui/app/components/send_/send-content/send-to-row/send-to-row.utils.js @@ -0,0 +1,17 @@ +const { isValidAddress } = require('../../../../util') + +function getToErrorObject (to) { + let toError = null + + if (!to) { + toError = 'required' + } else if (!isValidAddress(to)) { + toError = 'invalidAddressRecipient' + } + + return { to: toError } +} + +module.exports = { + getToErrorObject +} diff --git a/ui/app/components/send_/send-content/send-to-row/tests/send-to-row-component.test.js b/ui/app/components/send_/send-content/send-to-row/tests/send-to-row-component.test.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-content/send-to-row/tests/send-to-row-component.test.js diff --git a/ui/app/components/send_/send-content/send-to-row/tests/send-to-row-container.test.js b/ui/app/components/send_/send-content/send-to-row/tests/send-to-row-container.test.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-content/send-to-row/tests/send-to-row-container.test.js diff --git a/ui/app/components/send_/send-content/send-to-row/tests/send-to-row-selectors.test.js b/ui/app/components/send_/send-content/send-to-row/tests/send-to-row-selectors.test.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-content/send-to-row/tests/send-to-row-selectors.test.js diff --git a/ui/app/components/send_/send-content/tests/send-content-component.test.js b/ui/app/components/send_/send-content/tests/send-content-component.test.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-content/tests/send-content-component.test.js diff --git a/ui/app/components/send_/send-footer/README.md b/ui/app/components/send_/send-footer/README.md new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-footer/README.md diff --git a/ui/app/components/send_/send-footer/send-footer.component.js b/ui/app/components/send_/send-footer/send-footer.component.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-footer/send-footer.component.js diff --git a/ui/app/components/send_/send-footer/send-footer.container.js b/ui/app/components/send_/send-footer/send-footer.container.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-footer/send-footer.container.js diff --git a/ui/app/components/send_/send-footer/send-footer.scss b/ui/app/components/send_/send-footer/send-footer.scss new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-footer/send-footer.scss diff --git a/ui/app/components/send_/send-footer/send-footer.selectors.js b/ui/app/components/send_/send-footer/send-footer.selectors.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-footer/send-footer.selectors.js diff --git a/ui/app/components/send_/send-footer/send-footer.utils.js b/ui/app/components/send_/send-footer/send-footer.utils.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-footer/send-footer.utils.js diff --git a/ui/app/components/send_/send-footer/tests/send-footer-component.test.js b/ui/app/components/send_/send-footer/tests/send-footer-component.test.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-footer/tests/send-footer-component.test.js diff --git a/ui/app/components/send_/send-footer/tests/send-footer-container.test.js b/ui/app/components/send_/send-footer/tests/send-footer-container.test.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-footer/tests/send-footer-container.test.js diff --git a/ui/app/components/send_/send-footer/tests/send-footer-selectors.test.js b/ui/app/components/send_/send-footer/tests/send-footer-selectors.test.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-footer/tests/send-footer-selectors.test.js diff --git a/ui/app/components/send_/send-footer/tests/send-footer-utils.test.js b/ui/app/components/send_/send-footer/tests/send-footer-utils.test.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-footer/tests/send-footer-utils.test.js diff --git a/ui/app/components/send_/send-header/README.md b/ui/app/components/send_/send-header/README.md new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-header/README.md diff --git a/ui/app/components/send_/send-header/send-header.component.js b/ui/app/components/send_/send-header/send-header.component.js new file mode 100644 index 000000000..99adfc7e8 --- /dev/null +++ b/ui/app/components/send_/send-header/send-header.component.js @@ -0,0 +1,32 @@ +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import PageContainerHeader from '../../page-container/page-container-header.component' + +export default class SendHeader extends Component { + + static propTypes = { + isToken: PropTypes.bool, + clearSend: PropTypes.func, + goHome: PropTypes.func, + }; + + render () { + const { isToken, clearSend, goHome } = this.props + + return ( + <PageContainerHeader + title={isToken ? this.context.t('sendTokens') : this.context.t('sendETH')} + subtitle={this.context.t('onlySendToEtherAddress')} + onClose={() => { + clearSend() + goHome() + }} + /> + ); + } + +} + +SendHeader.contextTypes = { + t: PropTypes.func, +} diff --git a/ui/app/components/send_/send-header/send-header.container.js b/ui/app/components/send_/send-header/send-header.container.js new file mode 100644 index 000000000..a4d3ac54f --- /dev/null +++ b/ui/app/components/send_/send-header/send-header.container.js @@ -0,0 +1,19 @@ +import { connect } from 'react-redux' +import { goHome, clearSend } from '../../../actions' +import SendHeader from './send-header.component' +import { getSelectedToken } from '../../../selectors' + +export default connect(mapStateToProps, mapDispatchToProps)(SendHeader) + +function mapStateToProps (state) { + return { + isToken: Boolean(getSelectedToken(state)) + } +} + +function mapDispatchToProps (dispatch) { + return { + goHome: () => dispatch(goHome()), + clearSend: () => dispatch(clearSend()), + } +} diff --git a/ui/app/components/send_/send-header/tests/send-header-component.test.js b/ui/app/components/send_/send-header/tests/send-header-component.test.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-header/tests/send-header-component.test.js diff --git a/ui/app/components/send_/send-header/tests/send-header-container.test.js b/ui/app/components/send_/send-header/tests/send-header-container.test.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send-header/tests/send-header-container.test.js diff --git a/ui/app/components/send_/send.component.js b/ui/app/components/send_/send.component.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send.component.js diff --git a/ui/app/components/send_/send.container.js b/ui/app/components/send_/send.container.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send.container.js diff --git a/ui/app/components/send_/send.scss b/ui/app/components/send_/send.scss new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send.scss diff --git a/ui/app/components/send_/send.selectors.js b/ui/app/components/send_/send.selectors.js new file mode 100644 index 000000000..8c088098e --- /dev/null +++ b/ui/app/components/send_/send.selectors.js @@ -0,0 +1,217 @@ +import { valuesFor } from '../../util' +import abi from 'human-standard-token-abi' +import { + multiplyCurrencies, +} from './conversion-util' + +const selectors = { + getSelectedAddress, + getSelectedIdentity, + getSelectedAccount, + getSelectedToken, + getSelectedTokenExchangeRate, + getTokenExchangeRate, + conversionRateSelector, + transactionsSelector, + accountsWithSendEtherInfoSelector, + getCurrentAccountWithSendEtherInfo, + getGasPrice, + getGasLimit, + getForceGasMin, + getAddressBook, + getSendFrom, + getCurrentCurrency, + getSendAmount, + getSelectedTokenToFiatRate, + getSelectedTokenContract, + autoAddToBetaUI, + getSendMaxModeState, + getCurrentViewContext, + getSendErrors, + getSendTo, + getCurrentNetwork, +} + +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 conversionRateSelector (state) { + return state.metamask.conversionRate +} + +function getAddressBook (state) { + return state.metamask.addressBook +} + +function accountsWithSendEtherInfoSelector (state) { + const { + accounts, + identities, + } = state.metamask + + const accountsWithSendEtherInfo = Object.entries(accounts).map(([key, account]) => { + return Object.assign({}, account, identities[key]) + }) + + 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 getGasLimit (state) { + return state.metamask.send.gasLimit +} + +function getForceGasMin (state) { + return state.metamask.send.forceGasMin +} + +function getSendFrom (state) { + return state.metamask.send.from +} + +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 = conversionRateSelector(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 + const autoAddTokensThreshold = 1 + + const numberOfTransactions = state.metamask.selectedAddressTxList.length + const numberOfAccounts = Object.keys(state.metamask.accounts).length + const numberOfTokensAdded = state.metamask.tokens.length + + const userPassesThreshold = (numberOfTransactions > autoAddTransactionThreshold) && + (numberOfAccounts > autoAddAccountsThreshold) && + (numberOfTokensAdded > autoAddTokensThreshold) + const userIsNotInBeta = !state.metamask.featureFlags.betaUI + + return userIsNotInBeta && userPassesThreshold +} + +function getCurrentViewContext (state) { + const { currentView = {} } = state.appState + return currentView.context +} + +function getSendErrors (state) { + return state.metamask.send.errors +} + +function getSendTo (state) { + return state.metamask.send.to +} + +function getSendToAccounts (state) { + const fromAccounts = accountsWithSendEtherInfoSelector(state) + const addressBookAccounts = getAddressBook(state) + const allAccounts = [...fromAccounts, ...addressBookAccounts] + // TODO: figure out exactly what the below returns and put a descriptive variable name on it + return Object.entries(allAccounts).map(([key, account]) => account) +} + +function getCurrentNetwork (state) { + return state.metamask.network +}
\ No newline at end of file diff --git a/ui/app/components/send_/send.utils.js b/ui/app/components/send_/send.utils.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/send.utils.js diff --git a/ui/app/components/send_/tests/send-component.test.js b/ui/app/components/send_/tests/send-component.test.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/tests/send-component.test.js diff --git a/ui/app/components/send_/tests/send-container.test.js b/ui/app/components/send_/tests/send-container.test.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/tests/send-container.test.js diff --git a/ui/app/components/send_/tests/send-selectors.test.js b/ui/app/components/send_/tests/send-selectors.test.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/tests/send-selectors.test.js diff --git a/ui/app/components/send_/tests/send-utils.test.js b/ui/app/components/send_/tests/send-utils.test.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/components/send_/tests/send-utils.test.js |