diff options
author | Dan Finlay <flyswatter@users.noreply.github.com> | 2017-06-13 01:26:40 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-06-13 01:26:40 +0800 |
commit | 3e1d648ec012af9a8fe6fc3b329338f7f7fc80e2 (patch) | |
tree | 7e84df2522037578f6761854f8316d0484d4b8a0 /ui/app/components | |
parent | 8d8eb0d8adb5edbfb9f34ed9bacd28ffd03b1e1d (diff) | |
parent | cd3362f941b8eae12adbb6ffe9d60d4a6195755f (diff) | |
download | tangerine-wallet-browser-3e1d648ec012af9a8fe6fc3b329338f7f7fc80e2.tar tangerine-wallet-browser-3e1d648ec012af9a8fe6fc3b329338f7f7fc80e2.tar.gz tangerine-wallet-browser-3e1d648ec012af9a8fe6fc3b329338f7f7fc80e2.tar.bz2 tangerine-wallet-browser-3e1d648ec012af9a8fe6fc3b329338f7f7fc80e2.tar.lz tangerine-wallet-browser-3e1d648ec012af9a8fe6fc3b329338f7f7fc80e2.tar.xz tangerine-wallet-browser-3e1d648ec012af9a8fe6fc3b329338f7f7fc80e2.tar.zst tangerine-wallet-browser-3e1d648ec012af9a8fe6fc3b329338f7f7fc80e2.zip |
Merge branch 'master' into gasupdater
Diffstat (limited to 'ui/app/components')
-rw-r--r-- | ui/app/components/copyable.js | 46 | ||||
-rw-r--r-- | ui/app/components/ens-input.js | 4 | ||||
-rw-r--r-- | ui/app/components/pending-tx.js | 50 |
3 files changed, 87 insertions, 13 deletions
diff --git a/ui/app/components/copyable.js b/ui/app/components/copyable.js new file mode 100644 index 000000000..a4f6f4bc6 --- /dev/null +++ b/ui/app/components/copyable.js @@ -0,0 +1,46 @@ +const Component = require('react').Component +const h = require('react-hyperscript') +const inherits = require('util').inherits + +const Tooltip = require('./tooltip') +const copyToClipboard = require('copy-to-clipboard') + +module.exports = Copyable + +inherits(Copyable, Component) +function Copyable () { + Component.call(this) + this.state = { + copied: false, + } +} + +Copyable.prototype.render = function () { + const props = this.props + const state = this.state + const { value, children } = props + const { copied } = state + + return h(Tooltip, { + title: copied ? 'Copied!' : 'Copy', + position: 'bottom', + }, h('span', { + style: { + cursor: 'pointer', + }, + onClick: (event) => { + event.preventDefault() + event.stopPropagation() + copyToClipboard(value) + this.debounceRestore() + }, + }, children)) +} + +Copyable.prototype.debounceRestore = function () { + this.setState({ copied: true }) + clearTimeout(this.timeout) + this.timeout = setTimeout(() => { + this.setState({ copied: false }) + }, 850) +} diff --git a/ui/app/components/ens-input.js b/ui/app/components/ens-input.js index 3e44d83af..43bb7ab22 100644 --- a/ui/app/components/ens-input.js +++ b/ui/app/components/ens-input.js @@ -21,6 +21,7 @@ EnsInput.prototype.render = function () { const opts = extend(props, { list: 'addresses', onChange: () => { + this.setState({ ensResolution: '0x0000000000000000000000000000000000000000' }) const network = this.props.network const networkHasEnsSupport = getNetworkEnsSupport(network) if (!networkHasEnsSupport) return @@ -95,12 +96,14 @@ EnsInput.prototype.lookupEnsName = function () { log.info(`ENS attempting to resolve name: ${recipient}`) this.ens.lookup(recipient.trim()) .then((address) => { + if (address === '0x0000000000000000000000000000000000000000') throw new Error('No address has been set for this name.') if (address !== ensResolution) { this.setState({ loadingEns: false, ensResolution: address, nickname: recipient.trim(), hoverText: address + '\nClick to Copy', + ensFailure: false, }) } }) @@ -108,6 +111,7 @@ EnsInput.prototype.lookupEnsName = function () { log.error(reason) return this.setState({ loadingEns: false, + ensResolution: '0x0000000000000000000000000000000000000000', ensFailure: true, hoverText: reason.message, }) diff --git a/ui/app/components/pending-tx.js b/ui/app/components/pending-tx.js index 0847a8d4c..4b1a00eca 100644 --- a/ui/app/components/pending-tx.js +++ b/ui/app/components/pending-tx.js @@ -7,10 +7,10 @@ const clone = require('clone') const ethUtil = require('ethereumjs-util') const BN = ethUtil.BN const hexToBn = require('../../../app/scripts/lib/hex-to-bn') - +const util = require('../util') const MiniAccountPanel = require('./mini-account-panel') +const Copyable = require('./copyable') const EthBalance = require('./eth-balance') -const util = require('../util') const addressSummary = util.addressSummary const nameForAddress = require('../../lib/contract-namer') const BNInput = require('./bn-as-decimal-input') @@ -44,6 +44,9 @@ PendingTx.prototype.render = function () { const account = props.accounts[address] const balance = account ? account.balance : '0x0' + // recipient check + const isValidAddress = !txParams.to || util.isValidAddress(txParams.to) + // Gas const gas = txParams.gas const gasBn = hexToBn(gas) @@ -94,11 +97,16 @@ PendingTx.prototype.render = function () { fontFamily: 'Montserrat Bold, Montserrat, sans-serif', }, }, identity.name), - h('span.font-small', { - style: { - fontFamily: 'Montserrat Light, Montserrat, sans-serif', - }, - }, addressSummary(address, 6, 4, false)), + + h(Copyable, { + value: ethUtil.toChecksumAddress(address), + }, [ + h('span.font-small', { + style: { + fontFamily: 'Montserrat Light, Montserrat, sans-serif', + }, + }, addressSummary(address, 6, 4, false)), + ]), h('span.font-small', { style: { @@ -262,6 +270,15 @@ PendingTx.prototype.render = function () { }, 'Transaction Error. Exception thrown in contract code.') : null, + !isValidAddress ? + h('.error', { + style: { + marginLeft: 50, + fontSize: '0.9em', + }, + }, 'Recipient address is invalid. Sending this transaction will result in a loss of ETH.') + : null, + insufficientBalance ? h('span.error', { style: { @@ -299,7 +316,7 @@ PendingTx.prototype.render = function () { type: 'submit', value: 'ACCEPT', style: { marginLeft: '10px' }, - disabled: insufficientBalance || !this.state.valid, + disabled: insufficientBalance || !this.state.valid || !isValidAddress, }), h('button.cancel.btn-red', { @@ -323,16 +340,23 @@ PendingTx.prototype.miniAccountPanelForRecipient = function () { imageSeed: txParams.to, picOrder: 'left', }, [ + h('span.font-small', { style: { fontFamily: 'Montserrat Bold, Montserrat, sans-serif', }, }, nameForAddress(txParams.to, props.identities)), - h('span.font-small', { - style: { - fontFamily: 'Montserrat Light, Montserrat, sans-serif', - }, - }, addressSummary(txParams.to, 6, 4, false)), + + h(Copyable, { + value: ethUtil.toChecksumAddress(txParams.to), + }, [ + h('span.font-small', { + style: { + fontFamily: 'Montserrat Light, Montserrat, sans-serif', + }, + }, addressSummary(txParams.to, 6, 4, false)), + ]), + ]) } else { return h(MiniAccountPanel, { |