From 441a7eec2899c6553004ced2245d17ef9cc33a51 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Wed, 29 Jun 2016 14:11:12 -0700 Subject: [PATCH 1/7] Add CopyButton component --- ui/app/components/copyButton.js | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 ui/app/components/copyButton.js diff --git a/ui/app/components/copyButton.js b/ui/app/components/copyButton.js new file mode 100644 index 000000000..74fd673c2 --- /dev/null +++ b/ui/app/components/copyButton.js @@ -0,0 +1,26 @@ +const Component = require('react').Component +const h = require('react-hyperscript') +const inherits = require('util').inherits +const copyToClipboard = require('copy-to-clipboard') + +module.exports = CopyButton + +inherits(CopyButton, Component) +function CopyButton () { + Component.call(this) +} + +CopyButton.prototype.render = function () { + const props = this.props + const value = props.value + + return h('img.cursor-pointer.color-orange', { + src: 'images/copy.svg', + title: 'Copy Address', + onClick: (event) => { + event.preventDefault() + event.stopPropagation() + copyToClipboard(value) + }, + }) +} From 5c57169219596e4637c59dd39c01812a4b1bb746 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Wed, 29 Jun 2016 14:11:31 -0700 Subject: [PATCH 2/7] Replace manual copy buttons with new CopyButton component --- ui/app/account-detail.js | 11 +++-------- ui/app/accounts/account-list-item.js | 12 +++--------- 2 files changed, 6 insertions(+), 17 deletions(-) diff --git a/ui/app/account-detail.js b/ui/app/account-detail.js index 7daa3a4dd..8a17e095a 100644 --- a/ui/app/account-detail.js +++ b/ui/app/account-detail.js @@ -3,7 +3,7 @@ const extend = require('xtend') const Component = require('react').Component const h = require('react-hyperscript') const connect = require('react-redux').connect -const copyToClipboard = require('copy-to-clipboard') +const CopyButton = require('./components/copyButton') const actions = require('./actions') const ReactCSSTransitionGroup = require('react-addons-css-transition-group') const valuesFor = require('./util').valuesFor @@ -105,13 +105,8 @@ AccountDetailScreen.prototype.render = function () { }, }, ethUtil.toChecksumAddress(selected)), - h('img.cursor-pointer.color-orange', { - src: 'images/copy.svg', - title: 'Copy Address', - onClick: () => copyToClipboard(ethUtil.toChecksumAddress(selected)), - style: { - margin: '0px 5px', - }, + h(CopyButton, { + value: ethUtil.toChecksumAddress(selected), }), h('img.cursor-pointer.color-orange', { diff --git a/ui/app/accounts/account-list-item.js b/ui/app/accounts/account-list-item.js index 6bba6e145..1010516e2 100644 --- a/ui/app/accounts/account-list-item.js +++ b/ui/app/accounts/account-list-item.js @@ -4,7 +4,7 @@ const inherits = require('util').inherits const ethUtil = require('ethereumjs-util') const EtherBalance = require('../components/eth-balance') -const copyToClipboard = require('copy-to-clipboard') +const CopyButton = require('../components/copyButton') const Identicon = require('../components/identicon') module.exports = NewComponent @@ -61,14 +61,8 @@ NewComponent.prototype.render = function () { margin: '0 20px', }, }, [ - h('img.cursor-pointer.color-orange', { - title: 'Copy Address', - src: 'images/copy.svg', - onClick: (event) => { - event.stopPropagation() - event.preventDefault() - copyToClipboard(ethUtil.toChecksumAddress(identity.address)) - }, + h(CopyButton, { + value: ethUtil.toChecksumAddress(identity.address), }), ]), ]) From fb92b8a5fe62bcdb4e56eab669134c46ba2e8929 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Wed, 29 Jun 2016 14:12:58 -0700 Subject: [PATCH 3/7] Add copy button to transaction list --- ui/app/components/transaction-list-item.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ui/app/components/transaction-list-item.js b/ui/app/components/transaction-list-item.js index 82176059f..b1fc0d5f3 100644 --- a/ui/app/components/transaction-list-item.js +++ b/ui/app/components/transaction-list-item.js @@ -5,6 +5,7 @@ const inherits = require('util').inherits const EtherBalance = require('./eth-balance') const addressSummary = require('../util').addressSummary const explorerLink = require('../../lib/explorer-link') +const CopyButton = require('./copyButton') const vreme = new (require('vreme')) const TransactionIcon = require('./transaction-list-item-icon') @@ -67,6 +68,8 @@ TransactionListItem.prototype.render = function () { recipientField(txParams, transaction, isTx, isMsg), ]), + transaction.hash ? h(CopyButton, { value: transaction.hash }) : null, + isTx ? h(EtherBalance, { value: txParams.value, }) : h('.flex-column'), From 7f92a8da06b9e40705a0d1678480b302bd9d5607 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Wed, 29 Jun 2016 14:39:25 -0700 Subject: [PATCH 4/7] Use clipboard icon for copy button --- ui/app/components/copyButton.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/ui/app/components/copyButton.js b/ui/app/components/copyButton.js index 74fd673c2..1fdc3f822 100644 --- a/ui/app/components/copyButton.js +++ b/ui/app/components/copyButton.js @@ -14,9 +14,14 @@ CopyButton.prototype.render = function () { const props = this.props const value = props.value - return h('img.cursor-pointer.color-orange', { - src: 'images/copy.svg', - title: 'Copy Address', + return h('i.fa.fa-clipboard.cursor-pointer.color-orange', { + title: props.title || 'Copy', + style: { + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + margin: '5px', + }, onClick: (event) => { event.preventDefault() event.stopPropagation() From 57c8922817700f5488a129d91680d1765efe160d Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Wed, 29 Jun 2016 14:40:13 -0700 Subject: [PATCH 5/7] Bump changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ffec75cb..48ace019e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Current Master +- Add copy transaction hash button to completed transaction list items. + ## 2.4.5 2016-06-29 - Fixed bug where MetaMask interfered with PDF loading. From 78e6ed22befcb09b4d5c5e10862b8bfdf1d5fb1a Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Wed, 29 Jun 2016 15:57:59 -0700 Subject: [PATCH 6/7] Add tooltip to copy button --- package.json | 1 + ui/app/components/copyButton.js | 53 ++++++++++++++++++++++++++------- ui/css.js | 1 + 3 files changed, 44 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index cafca2672..efa652730 100644 --- a/package.json +++ b/package.json @@ -54,6 +54,7 @@ "react-dom": "^15.0.2", "react-hyperscript": "^2.2.2", "react-redux": "^4.4.5", + "react-tooltip-component": "^0.3.0", "readable-stream": "^2.1.2", "redux": "^3.0.5", "redux-logger": "^2.3.1", diff --git a/ui/app/components/copyButton.js b/ui/app/components/copyButton.js index 1fdc3f822..182d7a670 100644 --- a/ui/app/components/copyButton.js +++ b/ui/app/components/copyButton.js @@ -3,6 +3,8 @@ const h = require('react-hyperscript') const inherits = require('util').inherits const copyToClipboard = require('copy-to-clipboard') +const Tooltip = require('react-tooltip-component') + module.exports = CopyButton inherits(CopyButton, Component) @@ -10,22 +12,51 @@ function CopyButton () { Component.call(this) } +// As parameters, accepts: +// "value", which is the value to copy (mandatory) +// "title", which is the text to show on hover (optional, defaults to 'Copy') CopyButton.prototype.render = function () { const props = this.props - const value = props.value + const state = this.state || {} - return h('i.fa.fa-clipboard.cursor-pointer.color-orange', { - title: props.title || 'Copy', + const value = props.value + const copied = state.copied + + const message = copied ? 'Copied' : props.title || ' Copy ' + + return h('.copy-button', { style: { display: 'flex', - justifyContent: 'center', alignItems: 'center', - margin: '5px', }, - onClick: (event) => { - event.preventDefault() - event.stopPropagation() - copyToClipboard(value) - }, - }) + }, [ + + h(Tooltip, { + position: 'top', + title: message, + }, [ + h('i.fa.fa-clipboard.cursor-pointer.color-orange', { + style: { + margin: '5px', + }, + onClick: (event) => { + event.preventDefault() + event.stopPropagation() + copyToClipboard(value) + this.debounceRestore() + }, + }), + ]), + + ]) +} + +CopyButton.prototype.debounceRestore = function() { + + this.setState({ copied: true }) + clearTimeout(this.timeout) + this.timeout = setTimeout(() => { + this.setState({ copied: false }) + }, 850) + } diff --git a/ui/css.js b/ui/css.js index f6abb0d7a..01f317acd 100644 --- a/ui/css.js +++ b/ui/css.js @@ -9,6 +9,7 @@ var cssFiles = { 'lib.css': fs.readFileSync(path.join(__dirname, '/app/css/lib.css'), 'utf8'), 'index.css': fs.readFileSync(path.join(__dirname, '/app/css/index.css'), 'utf8'), 'transitions.css': fs.readFileSync(path.join(__dirname, '/app/css/transitions.css'), 'utf8'), + 'react-tooltip-component.css': fs.readFileSync(path.join(__dirname, '..', 'node_modules', 'react-tooltip-component', 'dist', 'react-tooltip-component.css'), 'utf8'), } function bundleCss () { From 2880f8631c4de09860b2be01c90b4b30d08c8415 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Wed, 29 Jun 2016 16:21:38 -0700 Subject: [PATCH 7/7] Unify tooltip styles Made a local tooltip component for replicating our tooltip styles wherever we use tooltips. Applied that tooltip to other items that had tooltips. --- ui/app/account-detail.js | 34 +++++++++++++++++++++------------ ui/app/app.js | 26 +++++++++++++------------ ui/app/components/copyButton.js | 3 +-- ui/app/components/tooltip.js | 22 +++++++++++++++++++++ 4 files changed, 59 insertions(+), 26 deletions(-) create mode 100644 ui/app/components/tooltip.js diff --git a/ui/app/account-detail.js b/ui/app/account-detail.js index 8a17e095a..02a807dbb 100644 --- a/ui/app/account-detail.js +++ b/ui/app/account-detail.js @@ -14,6 +14,7 @@ const TransactionList = require('./components/transaction-list') const ExportAccountView = require('./components/account-export') const ethUtil = require('ethereumjs-util') const EditableLabel = require('./components/editable-label') +const Tooltip = require('./components/tooltip') module.exports = connect(mapStateToProps)(AccountDetailScreen) @@ -109,19 +110,28 @@ AccountDetailScreen.prototype.render = function () { value: ethUtil.toChecksumAddress(selected), }), - h('img.cursor-pointer.color-orange', { - src: 'images/key-32.png', + h(Tooltip, { title: 'Export Private Key', - onClick: () => this.requestAccountExport(selected), - style: { - margin: '0px 5px', - width: '20px', - height: '20px', - position: 'relative', - top: '3px', - right: '4px', - }, - }), + }, [ + h('div', { + style: { + margin: '5px', + }, + }, [ + h('img.cursor-pointer.color-orange', { + src: 'images/key-32.png', + onClick: () => this.requestAccountExport(selected), + style: { + margin: '0px 5px', + width: '20px', + height: '20px', + position: 'relative', + top: '3px', + right: '4px', + }, + }), + ]), + ]), ]), diff --git a/ui/app/app.js b/ui/app/app.js index 8297ed796..525681166 100644 --- a/ui/app/app.js +++ b/ui/app/app.js @@ -26,6 +26,7 @@ const SandwichExpando = require('sandwich-expando') const MenuDroppo = require('menu-droppo') const DropMenuItem = require('./components/drop-menu-item') const NetworkIndicator = require('./components/network') +const Tooltip = require('./components/tooltip') module.exports = connect(mapStateToProps)(App) @@ -152,18 +153,19 @@ App.prototype.renderAppBar = function () { }, [ // small accounts nav - h('img.cursor-pointer.color-orange', { - src: 'images/switch_acc.svg', - style: { - width: '23.5px', - marginRight: '8px', - }, - title: 'Switch Accounts', - onClick: (event) => { - event.stopPropagation() - this.props.dispatch(actions.showAccountsPage()) - }, - }), + h(Tooltip, { title: 'Switch Accounts' }, [ + h('img.cursor-pointer.color-orange', { + src: 'images/switch_acc.svg', + style: { + width: '23.5px', + marginRight: '8px', + }, + onClick: (event) => { + event.stopPropagation() + this.props.dispatch(actions.showAccountsPage()) + }, + }), + ]), // hamburger h(SandwichExpando, { diff --git a/ui/app/components/copyButton.js b/ui/app/components/copyButton.js index 182d7a670..a01603585 100644 --- a/ui/app/components/copyButton.js +++ b/ui/app/components/copyButton.js @@ -3,7 +3,7 @@ const h = require('react-hyperscript') const inherits = require('util').inherits const copyToClipboard = require('copy-to-clipboard') -const Tooltip = require('react-tooltip-component') +const Tooltip = require('./tooltip') module.exports = CopyButton @@ -32,7 +32,6 @@ CopyButton.prototype.render = function () { }, [ h(Tooltip, { - position: 'top', title: message, }, [ h('i.fa.fa-clipboard.cursor-pointer.color-orange', { diff --git a/ui/app/components/tooltip.js b/ui/app/components/tooltip.js new file mode 100644 index 000000000..4eab8611e --- /dev/null +++ b/ui/app/components/tooltip.js @@ -0,0 +1,22 @@ +const Component = require('react').Component +const h = require('react-hyperscript') +const inherits = require('util').inherits +const ReactTooltip = require('react-tooltip-component') + +module.exports = Tooltip + +inherits(Tooltip, Component) +function Tooltip () { + Component.call(this) +} + +Tooltip.prototype.render = function () { + const props = this.props + + return h(ReactTooltip, { + position: 'left', + title: props.title, + fixed: false, + }, props.children) + +}