From ec097c8e3473826f29d988bb6e754345f494913e Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Sun, 4 Jun 2017 22:13:28 -0700 Subject: Add copy links to mini tx panels --- ui/app/components/pending-tx.js | 48 ++++++++++++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 10 deletions(-) (limited to 'ui') diff --git a/ui/app/components/pending-tx.js b/ui/app/components/pending-tx.js index b46f715bc..4a62746d6 100644 --- a/ui/app/components/pending-tx.js +++ b/ui/app/components/pending-tx.js @@ -9,6 +9,8 @@ const BN = ethUtil.BN const hexToBn = require('../../../app/scripts/lib/hex-to-bn') const MiniAccountPanel = require('./mini-account-panel') +const Tooltip = require('./tooltip') +const copyToClipboard = require('copy-to-clipboard') const EthBalance = require('./eth-balance') const util = require('../util') const addressSummary = util.addressSummary @@ -93,11 +95,23 @@ 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(Tooltip, { + title: 'Copy address', + position: 'bottom', + }, [ + h('span.font-small', { + onClick: (event) => { + event.preventDefault() + event.stopPropagation() + copyToClipboard(ethUtil.toChecksumAddress(address)) + }, + style: { + cursor: 'pointer', + fontFamily: 'Montserrat Light, Montserrat, sans-serif', + }, + }, addressSummary(address, 6, 4, false)), + ]), h('span.font-small', { style: { @@ -322,16 +336,30 @@ 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(Tooltip, { + title: 'Copy address', + position: 'bottom', + }, [ + h('span.font-small', { + onClick: (event) => { + event.preventDefault() + event.stopPropagation() + copyToClipboard(ethUtil.toChecksumAddress(txParams.to)) + }, + style: { + cursor: 'pointer', + fontFamily: 'Montserrat Light, Montserrat, sans-serif', + }, + }, addressSummary(txParams.to, 6, 4, false)), + ]), + ]) } else { return h(MiniAccountPanel, { -- cgit v1.2.3 From 773b36b0de5613f1f6bda1caba08ee240a14ab32 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Sun, 4 Jun 2017 22:21:37 -0700 Subject: Move address copying into reusable component "copyable" component allows any elements to be wrapped to include: - a tool tip that changes/debounces its label when clicked. - a customizable copyable value. Fixes #1539 --- ui/app/components/copyable.js | 49 +++++++++++++++++++++++++++++++++++++++++ ui/app/components/pending-tx.js | 25 +++++---------------- 2 files changed, 54 insertions(+), 20 deletions(-) create mode 100644 ui/app/components/copyable.js (limited to 'ui') diff --git a/ui/app/components/copyable.js b/ui/app/components/copyable.js new file mode 100644 index 000000000..9b785a77e --- /dev/null +++ b/ui/app/components/copyable.js @@ -0,0 +1,49 @@ +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', + style: { + cursor: 'pointer', + }, + }, 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/pending-tx.js b/ui/app/components/pending-tx.js index 4a62746d6..4961db5de 100644 --- a/ui/app/components/pending-tx.js +++ b/ui/app/components/pending-tx.js @@ -9,8 +9,7 @@ const BN = ethUtil.BN const hexToBn = require('../../../app/scripts/lib/hex-to-bn') const MiniAccountPanel = require('./mini-account-panel') -const Tooltip = require('./tooltip') -const copyToClipboard = require('copy-to-clipboard') +const Copyable = require('./copyable') const EthBalance = require('./eth-balance') const util = require('../util') const addressSummary = util.addressSummary @@ -96,18 +95,11 @@ PendingTx.prototype.render = function () { }, }, identity.name), - h(Tooltip, { - title: 'Copy address', - position: 'bottom', + h(Copyable, { + value: ethUtil.toChecksumAddress(address), }, [ h('span.font-small', { - onClick: (event) => { - event.preventDefault() - event.stopPropagation() - copyToClipboard(ethUtil.toChecksumAddress(address)) - }, style: { - cursor: 'pointer', fontFamily: 'Montserrat Light, Montserrat, sans-serif', }, }, addressSummary(address, 6, 4, false)), @@ -343,18 +335,11 @@ PendingTx.prototype.miniAccountPanelForRecipient = function () { }, }, nameForAddress(txParams.to, props.identities)), - h(Tooltip, { - title: 'Copy address', - position: 'bottom', + h(Copyable, { + value: ethUtil.toChecksumAddress(txParams.to), }, [ h('span.font-small', { - onClick: (event) => { - event.preventDefault() - event.stopPropagation() - copyToClipboard(ethUtil.toChecksumAddress(txParams.to)) - }, style: { - cursor: 'pointer', fontFamily: 'Montserrat Light, Montserrat, sans-serif', }, }, addressSummary(txParams.to, 6, 4, false)), -- cgit v1.2.3 From 8dc6aa9c4c4f11e08eee0688c210324b313b710b Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Sun, 4 Jun 2017 22:26:32 -0700 Subject: Remove dead style code --- ui/app/components/copyable.js | 3 --- 1 file changed, 3 deletions(-) (limited to 'ui') diff --git a/ui/app/components/copyable.js b/ui/app/components/copyable.js index 9b785a77e..a4f6f4bc6 100644 --- a/ui/app/components/copyable.js +++ b/ui/app/components/copyable.js @@ -24,9 +24,6 @@ Copyable.prototype.render = function () { return h(Tooltip, { title: copied ? 'Copied!' : 'Copy', position: 'bottom', - style: { - cursor: 'pointer', - }, }, h('span', { style: { cursor: 'pointer', -- cgit v1.2.3 From bb6e41963d42a91ecc34a728b7c0c18d26e6cd9f Mon Sep 17 00:00:00 2001 From: frankiebee Date: Mon, 5 Jun 2017 11:40:20 -0700 Subject: Dissallow transactions to be sent to 0x0000000000000000000000000000000000000000 --- ui/app/components/ens-input.js | 1 + ui/app/components/pending-tx.js | 14 +++++++++++++- ui/app/conf-tx.js | 1 + ui/app/send.js | 2 +- 4 files changed, 16 insertions(+), 2 deletions(-) (limited to 'ui') diff --git a/ui/app/components/ens-input.js b/ui/app/components/ens-input.js index 3e44d83af..11e0fb36d 100644 --- a/ui/app/components/ens-input.js +++ b/ui/app/components/ens-input.js @@ -95,6 +95,7 @@ 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, diff --git a/ui/app/components/pending-tx.js b/ui/app/components/pending-tx.js index b46f715bc..e8bf32d92 100644 --- a/ui/app/components/pending-tx.js +++ b/ui/app/components/pending-tx.js @@ -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 === '0x0000000000000000000000000000000000000000') + // Gas const gas = txParams.gas const gasBn = hexToBn(gas) @@ -261,6 +264,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: { @@ -298,7 +310,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', { diff --git a/ui/app/conf-tx.js b/ui/app/conf-tx.js index 008627ce6..4ae81f35f 100644 --- a/ui/app/conf-tx.js +++ b/ui/app/conf-tx.js @@ -48,6 +48,7 @@ ConfirmTxScreen.prototype.render = function () { var txParams = txData.params || {} var isNotification = isPopupOrNotification() === 'notification' + log.info(`rendering a combined ${unconfTxList.length} unconf msg & txs`) if (unconfTxList.length === 0) return h(Loading, { isLoading: true }) diff --git a/ui/app/send.js b/ui/app/send.js index fd6994145..e0896035e 100644 --- a/ui/app/send.js +++ b/ui/app/send.js @@ -262,7 +262,7 @@ SendTransactionScreen.prototype.onSubmit = function () { return this.props.dispatch(actions.displayWarning(message)) } - if ((!util.isValidAddress(recipient) && !txData) || (!recipient && !txData)) { + if ((!util.isValidAddress(recipient) && !txData) || (!recipient && !txData) || (recipient === '0x0000000000000000000000000000000000000000')) { message = 'Recipient address is invalid.' return this.props.dispatch(actions.displayWarning(message)) } -- cgit v1.2.3 From 37fd32025f9cb5dffb601011e2442efee59e3595 Mon Sep 17 00:00:00 2001 From: frankiebee Date: Mon, 5 Jun 2017 12:00:01 -0700 Subject: Fix punctuation --- ui/app/components/pending-tx.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ui') diff --git a/ui/app/components/pending-tx.js b/ui/app/components/pending-tx.js index e8bf32d92..2d4dc26a2 100644 --- a/ui/app/components/pending-tx.js +++ b/ui/app/components/pending-tx.js @@ -270,7 +270,7 @@ PendingTx.prototype.render = function () { marginLeft: 50, fontSize: '0.9em', }, - }, 'Recipient address is invalid sending this transaction will result in a loss of ETH.') + }, 'Recipient address is invalid. Sending this transaction will result in a loss of ETH.') : null, insufficientBalance ? -- cgit v1.2.3 From 653319be1055b8ff0a36cb334c93ac7435f1fc5c Mon Sep 17 00:00:00 2001 From: frankiebee Date: Mon, 5 Jun 2017 12:09:19 -0700 Subject: move address check to util.isValidAddress --- ui/app/components/pending-tx.js | 4 ++-- ui/app/send.js | 2 +- ui/app/util.js | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) (limited to 'ui') diff --git a/ui/app/components/pending-tx.js b/ui/app/components/pending-tx.js index 2d4dc26a2..56c466506 100644 --- a/ui/app/components/pending-tx.js +++ b/ui/app/components/pending-tx.js @@ -7,7 +7,7 @@ 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 EthBalance = require('./eth-balance') const util = require('../util') @@ -45,7 +45,7 @@ PendingTx.prototype.render = function () { const balance = account ? account.balance : '0x0' // recipient check - const isValidAddress = !(txParams.to === '0x0000000000000000000000000000000000000000') + const isValidAddress = util.isValidAddress(txParams.to) // Gas const gas = txParams.gas diff --git a/ui/app/send.js b/ui/app/send.js index e0896035e..75a600dee 100644 --- a/ui/app/send.js +++ b/ui/app/send.js @@ -262,7 +262,7 @@ SendTransactionScreen.prototype.onSubmit = function () { return this.props.dispatch(actions.displayWarning(message)) } - if ((!util.isValidAddress(recipient) && !txData) || (!recipient && !txData) || (recipient === '0x0000000000000000000000000000000000000000')) { + if ((!util.isValidAddress(recipient) && !txData) || (!recipient && !txData) { message = 'Recipient address is invalid.' return this.props.dispatch(actions.displayWarning(message)) } diff --git a/ui/app/util.js b/ui/app/util.js index 7a56bf6a0..ac3f42c6b 100644 --- a/ui/app/util.js +++ b/ui/app/util.js @@ -61,6 +61,7 @@ function miniAddressSummary (address) { function isValidAddress (address) { var prefixed = ethUtil.addHexPrefix(address) + if (address === '0x0000000000000000000000000000000000000000') return false return (isAllOneCase(prefixed) && ethUtil.isValidAddress(prefixed)) || ethUtil.isValidChecksumAddress(prefixed) } -- cgit v1.2.3 From 0f69a09823928ec6aaf5189cf4d4f50c52c9debb Mon Sep 17 00:00:00 2001 From: frankiebee Date: Mon, 5 Jun 2017 12:22:02 -0700 Subject: Fix linting error --- ui/app/components/pending-tx.js | 1 - ui/app/send.js | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'ui') diff --git a/ui/app/components/pending-tx.js b/ui/app/components/pending-tx.js index 56c466506..18c378781 100644 --- a/ui/app/components/pending-tx.js +++ b/ui/app/components/pending-tx.js @@ -10,7 +10,6 @@ const hexToBn = require('../../../app/scripts/lib/hex-to-bn') const util = require('../util') const MiniAccountPanel = require('./mini-account-panel') 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') diff --git a/ui/app/send.js b/ui/app/send.js index 75a600dee..fd6994145 100644 --- a/ui/app/send.js +++ b/ui/app/send.js @@ -262,7 +262,7 @@ SendTransactionScreen.prototype.onSubmit = function () { return this.props.dispatch(actions.displayWarning(message)) } - if ((!util.isValidAddress(recipient) && !txData) || (!recipient && !txData) { + if ((!util.isValidAddress(recipient) && !txData) || (!recipient && !txData)) { message = 'Recipient address is invalid.' return this.props.dispatch(actions.displayWarning(message)) } -- cgit v1.2.3 From ec99bfd5531922e7d153709c1a77f1c40cae9e99 Mon Sep 17 00:00:00 2001 From: frankiebee Date: Mon, 5 Jun 2017 12:37:29 -0700 Subject: set the ensResolution to an invalid address if an error ocurs durring look up --- ui/app/components/ens-input.js | 1 + 1 file changed, 1 insertion(+) (limited to 'ui') diff --git a/ui/app/components/ens-input.js b/ui/app/components/ens-input.js index 11e0fb36d..16a3a684c 100644 --- a/ui/app/components/ens-input.js +++ b/ui/app/components/ens-input.js @@ -109,6 +109,7 @@ EnsInput.prototype.lookupEnsName = function () { log.error(reason) return this.setState({ loadingEns: false, + ensResolution: '0x0000000000000000000000000000000000000000', ensFailure: true, hoverText: reason.message, }) -- cgit v1.2.3 From 94fedd1fc9d44054670b9f60ae6f92b409e7b25e Mon Sep 17 00:00:00 2001 From: frankiebee Date: Mon, 5 Jun 2017 13:00:15 -0700 Subject: Fix for quick switch on ENS names --- ui/app/components/ens-input.js | 2 ++ 1 file changed, 2 insertions(+) (limited to 'ui') diff --git a/ui/app/components/ens-input.js b/ui/app/components/ens-input.js index 16a3a684c..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 @@ -102,6 +103,7 @@ EnsInput.prototype.lookupEnsName = function () { ensResolution: address, nickname: recipient.trim(), hoverText: address + '\nClick to Copy', + ensFailure: false, }) } }) -- cgit v1.2.3 From c8f0802a8e63ca29c643d08ebc1b777520645246 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Mon, 5 Jun 2017 15:35:52 -0700 Subject: Fix bug that prevented publishing contracts --- ui/app/components/pending-tx.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ui') diff --git a/ui/app/components/pending-tx.js b/ui/app/components/pending-tx.js index a106f245b..e3b307b0b 100644 --- a/ui/app/components/pending-tx.js +++ b/ui/app/components/pending-tx.js @@ -45,7 +45,7 @@ PendingTx.prototype.render = function () { const balance = account ? account.balance : '0x0' // recipient check - const isValidAddress = util.isValidAddress(txParams.to) + const isValidAddress = !txParams.to || util.isValidAddress(txParams.to) // Gas const gas = txParams.gas -- cgit v1.2.3