aboutsummaryrefslogtreecommitdiffstats
path: root/ui/app/pages/send/send.component.js
diff options
context:
space:
mode:
Diffstat (limited to 'ui/app/pages/send/send.component.js')
-rw-r--r--ui/app/pages/send/send.component.js230
1 files changed, 230 insertions, 0 deletions
diff --git a/ui/app/pages/send/send.component.js b/ui/app/pages/send/send.component.js
new file mode 100644
index 000000000..5f0c9c9f2
--- /dev/null
+++ b/ui/app/pages/send/send.component.js
@@ -0,0 +1,230 @@
+import React from 'react'
+import PropTypes from 'prop-types'
+import PersistentForm from '../../../lib/persistent-form'
+import {
+ getAmountErrorObject,
+ getGasFeeErrorObject,
+ getToAddressForGasUpdate,
+ doesAmountErrorRequireUpdate,
+} from './send.utils'
+
+import SendHeader from './send-header'
+import SendContent from './send-content'
+import SendFooter from './send-footer'
+
+export default class SendTransactionScreen extends PersistentForm {
+
+ static propTypes = {
+ amount: PropTypes.string,
+ amountConversionRate: PropTypes.oneOfType([
+ PropTypes.string,
+ PropTypes.number,
+ ]),
+ blockGasLimit: PropTypes.string,
+ conversionRate: PropTypes.number,
+ editingTransactionId: PropTypes.string,
+ from: PropTypes.object,
+ gasLimit: PropTypes.string,
+ gasPrice: PropTypes.string,
+ gasTotal: PropTypes.string,
+ history: PropTypes.object,
+ network: PropTypes.string,
+ primaryCurrency: PropTypes.string,
+ recentBlocks: PropTypes.array,
+ selectedAddress: PropTypes.string,
+ selectedToken: PropTypes.object,
+ tokenBalance: PropTypes.string,
+ tokenContract: PropTypes.object,
+ fetchBasicGasEstimates: PropTypes.func,
+ updateAndSetGasTotal: PropTypes.func,
+ updateSendErrors: PropTypes.func,
+ updateSendTokenBalance: PropTypes.func,
+ scanQrCode: PropTypes.func,
+ qrCodeDetected: PropTypes.func,
+ qrCodeData: PropTypes.object,
+ }
+
+ static contextTypes = {
+ t: PropTypes.func,
+ }
+
+ componentWillReceiveProps (nextProps) {
+ if (nextProps.qrCodeData) {
+ if (nextProps.qrCodeData.type === 'address') {
+ const scannedAddress = nextProps.qrCodeData.values.address.toLowerCase()
+ const currentAddress = this.props.to && this.props.to.toLowerCase()
+ if (currentAddress !== scannedAddress) {
+ this.props.updateSendTo(scannedAddress)
+ this.updateGas({ to: scannedAddress })
+ // Clean up QR code data after handling
+ this.props.qrCodeDetected(null)
+ }
+ }
+ }
+ }
+
+ updateGas ({ to: updatedToAddress, amount: value, data } = {}) {
+ const {
+ amount,
+ blockGasLimit,
+ editingTransactionId,
+ gasLimit,
+ gasPrice,
+ recentBlocks,
+ selectedAddress,
+ selectedToken = {},
+ to: currentToAddress,
+ updateAndSetGasLimit,
+ } = this.props
+
+ updateAndSetGasLimit({
+ blockGasLimit,
+ editingTransactionId,
+ gasLimit,
+ gasPrice,
+ recentBlocks,
+ selectedAddress,
+ selectedToken,
+ to: getToAddressForGasUpdate(updatedToAddress, currentToAddress),
+ value: value || amount,
+ data,
+ })
+ }
+
+ componentDidUpdate (prevProps) {
+ const {
+ amount,
+ amountConversionRate,
+ conversionRate,
+ from: { address, balance },
+ gasTotal,
+ network,
+ primaryCurrency,
+ selectedToken,
+ tokenBalance,
+ updateSendErrors,
+ updateSendTokenBalance,
+ tokenContract,
+ } = this.props
+
+ const {
+ from: { balance: prevBalance },
+ gasTotal: prevGasTotal,
+ tokenBalance: prevTokenBalance,
+ network: prevNetwork,
+ selectedToken: prevSelectedToken,
+ } = prevProps
+
+ const uninitialized = [prevBalance, prevGasTotal].every(n => n === null)
+
+ const amountErrorRequiresUpdate = doesAmountErrorRequireUpdate({
+ balance,
+ gasTotal,
+ prevBalance,
+ prevGasTotal,
+ prevTokenBalance,
+ selectedToken,
+ tokenBalance,
+ })
+
+ if (amountErrorRequiresUpdate) {
+ const amountErrorObject = getAmountErrorObject({
+ amount,
+ amountConversionRate,
+ balance,
+ conversionRate,
+ gasTotal,
+ primaryCurrency,
+ selectedToken,
+ tokenBalance,
+ })
+ const gasFeeErrorObject = selectedToken
+ ? getGasFeeErrorObject({
+ amountConversionRate,
+ balance,
+ conversionRate,
+ gasTotal,
+ primaryCurrency,
+ selectedToken,
+ })
+ : { gasFee: null }
+ updateSendErrors(Object.assign(amountErrorObject, gasFeeErrorObject))
+ }
+
+ if (!uninitialized) {
+
+ if (network !== prevNetwork && network !== 'loading') {
+ updateSendTokenBalance({
+ selectedToken,
+ tokenContract,
+ address,
+ })
+ this.updateGas()
+ }
+ }
+
+ const prevTokenAddress = prevSelectedToken && prevSelectedToken.address
+ const selectedTokenAddress = selectedToken && selectedToken.address
+
+ if (selectedTokenAddress && prevTokenAddress !== selectedTokenAddress) {
+ this.updateSendToken()
+ }
+ }
+
+ componentDidMount () {
+ this.props.fetchBasicGasEstimates()
+ .then(() => {
+ this.updateGas()
+ })
+ }
+
+ componentWillMount () {
+ this.updateSendToken()
+
+ // Show QR Scanner modal if ?scan=true
+ if (window.location.search === '?scan=true') {
+ this.props.scanQrCode()
+
+ // Clear the queryString param after showing the modal
+ const cleanUrl = location.href.split('?')[0]
+ history.pushState({}, null, `${cleanUrl}`)
+ window.location.hash = '#send'
+ }
+ }
+
+ componentWillUnmount () {
+ this.props.resetSendState()
+ }
+
+ updateSendToken () {
+ const {
+ from: { address },
+ selectedToken,
+ tokenContract,
+ updateSendTokenBalance,
+ } = this.props
+
+ updateSendTokenBalance({
+ selectedToken,
+ tokenContract,
+ address,
+ })
+ }
+
+ render () {
+ const { history, showHexData } = this.props
+
+ return (
+ <div className="page-container">
+ <SendHeader history={history}/>
+ <SendContent
+ updateGas={(updateData) => this.updateGas(updateData)}
+ scanQrCode={_ => this.props.scanQrCode()}
+ showHexData={showHexData}
+ />
+ <SendFooter history={history}/>
+ </div>
+ )
+ }
+
+}