From 399c51c04831381da0b9013018763b43618de614 Mon Sep 17 00:00:00 2001 From: DavidNinja Date: Mon, 14 Aug 2017 21:29:21 -0700 Subject: cancel all txs --- ui/app/actions.js | 8 ++++++++ ui/app/conf-tx.js | 12 ++++++++++++ 2 files changed, 20 insertions(+) (limited to 'ui/app') diff --git a/ui/app/actions.js b/ui/app/actions.js index eafd04b4c..d5ee3cc31 100644 --- a/ui/app/actions.js +++ b/ui/app/actions.js @@ -105,6 +105,8 @@ var actions = { txError: txError, nextTx: nextTx, previousTx: previousTx, + cancelAllTx: cancelAllTx, + CANCEL_ALL_TX: 'CANCEL_ALL_TX', viewPendingTx: viewPendingTx, VIEW_PENDING_TX: 'VIEW_PENDING_TX', // app messages @@ -470,6 +472,12 @@ function cancelTx (txData) { } } +function cancelAllTx (txsData) { + return (dispatch) => { + txsData.forEach((txData) => dispatch(actions.cancelTx(txData))) + dispatch(actions.goHome()) + } +} // // initialize screen // diff --git a/ui/app/conf-tx.js b/ui/app/conf-tx.js index 34727ff78..d6ceb7ff5 100644 --- a/ui/app/conf-tx.js +++ b/ui/app/conf-tx.js @@ -89,6 +89,18 @@ ConfirmTxScreen.prototype.render = function () { }), ]), + h('h3', { + style: { + alignSelf: 'flex-end', + display: unconfTxList.length > 1 ? 'block' : 'none', + }, + }, [ + h('i.fa.fa-trash.fa-lg.cursor-pointer', { + title: 'Cancel All Pending Transactions', + onClick: () => props.dispatch(actions.cancelAllTx(unconfTxList)), + }), + ]), + warningIfExists(props.warning), currentTxView({ -- cgit From 39424cdf457e8348b50dde2588ad173aa4787fca Mon Sep 17 00:00:00 2001 From: davidp94 Date: Mon, 14 Aug 2017 21:35:57 -0700 Subject: remove unused action type --- ui/app/actions.js | 1 - 1 file changed, 1 deletion(-) (limited to 'ui/app') diff --git a/ui/app/actions.js b/ui/app/actions.js index d5ee3cc31..3b6b87b00 100644 --- a/ui/app/actions.js +++ b/ui/app/actions.js @@ -106,7 +106,6 @@ var actions = { nextTx: nextTx, previousTx: previousTx, cancelAllTx: cancelAllTx, - CANCEL_ALL_TX: 'CANCEL_ALL_TX', viewPendingTx: viewPendingTx, VIEW_PENDING_TX: 'VIEW_PENDING_TX', // app messages -- cgit From f52ef5d49657d126a2575c91c83481209e8ef0ab Mon Sep 17 00:00:00 2001 From: davidp94 Date: Mon, 14 Aug 2017 21:51:39 -0700 Subject: fix goHome --- ui/app/actions.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'ui/app') diff --git a/ui/app/actions.js b/ui/app/actions.js index 3b6b87b00..a692267cb 100644 --- a/ui/app/actions.js +++ b/ui/app/actions.js @@ -473,8 +473,12 @@ function cancelTx (txData) { function cancelAllTx (txsData) { return (dispatch) => { - txsData.forEach((txData) => dispatch(actions.cancelTx(txData))) - dispatch(actions.goHome()) + txsData.forEach((txData, i) => { + background.cancelTransaction(txData.id, () => { + dispatch(actions.completedTx(txData.id)) + i === txsData.length - 1 ? dispatch(actions.goHome()) : null + }) + }) } } // -- cgit From 3a87a30912e8c5e212f7d0cc5e01ed1f873bfe33 Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Thu, 7 Sep 2017 13:55:59 -0700 Subject: Fold submit and buy ether into one button slot --- ui/app/components/pending-tx.js | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) (limited to 'ui/app') diff --git a/ui/app/components/pending-tx.js b/ui/app/components/pending-tx.js index 5324ccd64..65f64adfe 100644 --- a/ui/app/components/pending-tx.js +++ b/ui/app/components/pending-tx.js @@ -66,6 +66,7 @@ PendingTx.prototype.render = function () { const balanceBn = hexToBn(balance) const insufficientBalance = balanceBn.lt(maxCost) + const buyDisabled = insufficientBalance || !this.state.valid || !isValidAddress || this.state.submitting this.inputs = [] @@ -297,14 +298,6 @@ PendingTx.prototype.render = function () { margin: '14px 25px', }, }, [ - - - insufficientBalance ? - h('button.btn-green', { - onClick: props.buyEth, - }, 'Buy Ether') - : null, - h('button', { onClick: (event) => { this.resetGasFields() @@ -312,13 +305,14 @@ PendingTx.prototype.render = function () { }, }, 'Reset'), - // Accept Button - h('input.confirm.btn-green', { - type: 'submit', - value: 'SUBMIT', - style: { marginLeft: '10px' }, - disabled: insufficientBalance || !this.state.valid || !isValidAddress || this.state.submitting, - }), + // Accept Button or Buy Button + insufficientBalance ? h('button.btn-green', { onClick: props.buyEth }, 'Buy Ether') : + h('input.confirm.btn-green', { + type: 'submit', + value: 'SUBMIT', + style: { marginLeft: '10px' }, + disabled: buyDisabled, + }), h('button.cancel.btn-red', { onClick: props.cancelTransaction, -- cgit From 41e9904d9b6a6a9b828c02c7fe34b8eefb631374 Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Thu, 7 Sep 2017 15:03:25 -0700 Subject: Convert icon to button. --- ui/app/components/pending-tx.js | 11 +++++++++++ ui/app/conf-tx.js | 19 +++++++------------ 2 files changed, 18 insertions(+), 12 deletions(-) (limited to 'ui/app') diff --git a/ui/app/components/pending-tx.js b/ui/app/components/pending-tx.js index 65f64adfe..4e7eeaecf 100644 --- a/ui/app/components/pending-tx.js +++ b/ui/app/components/pending-tx.js @@ -318,6 +318,17 @@ PendingTx.prototype.render = function () { onClick: props.cancelTransaction, }, 'Reject'), ]), + h('.flex-row.flex-space-around.conf-buttons', { + style: { + display: 'flex', + justifyContent: 'flex-end', + margin: '14px 25px', + }, + }, [ + h('button.cancel.btn-red', { + onClick: props.cancelAllTransactions, + }, 'Reject All'), + ]), ]), ]) ) diff --git a/ui/app/conf-tx.js b/ui/app/conf-tx.js index d6ceb7ff5..8d819181f 100644 --- a/ui/app/conf-tx.js +++ b/ui/app/conf-tx.js @@ -89,18 +89,6 @@ ConfirmTxScreen.prototype.render = function () { }), ]), - h('h3', { - style: { - alignSelf: 'flex-end', - display: unconfTxList.length > 1 ? 'block' : 'none', - }, - }, [ - h('i.fa.fa-trash.fa-lg.cursor-pointer', { - title: 'Cancel All Pending Transactions', - onClick: () => props.dispatch(actions.cancelAllTx(unconfTxList)), - }), - ]), - warningIfExists(props.warning), currentTxView({ @@ -117,6 +105,7 @@ ConfirmTxScreen.prototype.render = function () { buyEth: this.buyEth.bind(this, txParams.from || props.selectedAddress), sendTransaction: this.sendTransaction.bind(this), cancelTransaction: this.cancelTransaction.bind(this, txData), + cancelAllTransactions: this.cancelAllTransactions.bind(this, unconfTxList), signMessage: this.signMessage.bind(this, txData), signPersonalMessage: this.signPersonalMessage.bind(this, txData), cancelMessage: this.cancelMessage.bind(this, txData), @@ -163,6 +152,12 @@ ConfirmTxScreen.prototype.cancelTransaction = function (txData, event) { this.props.dispatch(actions.cancelTx(txData)) } +ConfirmTxScreen.prototype.cancelAllTransactions = function (unconfTxList, event) { + this.stopPropagation(event) + event.preventDefault() + this.props.dispatch(actions.cancelAllTx(unconfTxList)) +} + ConfirmTxScreen.prototype.signMessage = function (msgData, event) { log.info('conf-tx.js: signing message') var params = msgData.msgParams -- cgit From 27ba7f6ed3b0c55f6f5d7fa7e3829bdc06e0df9f Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Mon, 11 Sep 2017 14:12:35 -0700 Subject: Show reject all only when tx count is > 1 --- ui/app/components/pending-tx.js | 5 +++-- ui/app/conf-tx.js | 3 +++ 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'ui/app') diff --git a/ui/app/components/pending-tx.js b/ui/app/components/pending-tx.js index 4e7eeaecf..3e53d47f9 100644 --- a/ui/app/components/pending-tx.js +++ b/ui/app/components/pending-tx.js @@ -67,6 +67,7 @@ PendingTx.prototype.render = function () { const balanceBn = hexToBn(balance) const insufficientBalance = balanceBn.lt(maxCost) const buyDisabled = insufficientBalance || !this.state.valid || !isValidAddress || this.state.submitting + const showRejectAll = props.unconfTxListLength > 1 this.inputs = [] @@ -318,7 +319,7 @@ PendingTx.prototype.render = function () { onClick: props.cancelTransaction, }, 'Reject'), ]), - h('.flex-row.flex-space-around.conf-buttons', { + showRejectAll ? h('.flex-row.flex-space-around.conf-buttons', { style: { display: 'flex', justifyContent: 'flex-end', @@ -328,7 +329,7 @@ PendingTx.prototype.render = function () { h('button.cancel.btn-red', { onClick: props.cancelAllTransactions, }, 'Reject All'), - ]), + ]) : null, ]), ]) ) diff --git a/ui/app/conf-tx.js b/ui/app/conf-tx.js index 8d819181f..1ee4166f7 100644 --- a/ui/app/conf-tx.js +++ b/ui/app/conf-tx.js @@ -52,6 +52,8 @@ ConfirmTxScreen.prototype.render = function () { log.info(`rendering a combined ${unconfTxList.length} unconf msg & txs`) if (unconfTxList.length === 0) return h(Loading, { isLoading: true }) + const unconfTxListLength = unconfTxList.length + return ( h('.flex-column.flex-grow', [ @@ -101,6 +103,7 @@ ConfirmTxScreen.prototype.render = function () { conversionRate, currentCurrency, blockGasLimit, + unconfTxListLength, // Actions buyEth: this.buyEth.bind(this, txParams.from || props.selectedAddress), sendTransaction: this.sendTransaction.bind(this), -- cgit From 3a7d4a5d4e94d9a4c2556b161c5bad7dc00837a4 Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Mon, 11 Sep 2017 16:13:28 -0700 Subject: Basic private key download file functionality. --- ui/app/components/account-export.js | 39 ++++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 9 deletions(-) (limited to 'ui/app') diff --git a/ui/app/components/account-export.js b/ui/app/components/account-export.js index 330f73805..5bbdfca39 100644 --- a/ui/app/components/account-export.js +++ b/ui/app/components/account-export.js @@ -20,20 +20,21 @@ function mapStateToProps (state) { } ExportAccountView.prototype.render = function () { - var state = this.props - var accountDetail = state.accountDetail + const state = this.props + const accountDetail = state.accountDetail + const nickname = state.identities[state.address].name if (!accountDetail) return h('div') - var accountExport = accountDetail.accountExport + const accountExport = accountDetail.accountExport - var notExporting = accountExport === 'none' - var exportRequested = accountExport === 'requested' - var accountExported = accountExport === 'completed' + const notExporting = accountExport === 'none' + const exportRequested = accountExport === 'requested' + const accountExported = accountExport === 'completed' if (notExporting) return h('div') if (exportRequested) { - var warning = `Export private keys at your own risk.` + const warning = `Export private keys at your own risk.` return ( h('div', { style: { @@ -89,6 +90,8 @@ ExportAccountView.prototype.render = function () { } if (accountExported) { + const plainKey = ethUtil.stripHexPrefix(accountDetail.privateKey) + return h('div.privateKey', { style: { margin: '0 20px', @@ -105,10 +108,13 @@ ExportAccountView.prototype.render = function () { onClick: function (event) { copyToClipboard(ethUtil.stripHexPrefix(accountDetail.privateKey)) }, - }, ethUtil.stripHexPrefix(accountDetail.privateKey)), + }, plainKey), h('button', { onClick: () => this.props.dispatch(actions.backToAccountDetail(this.props.address)), }, 'Done'), + h('button', { + onClick: () => this.exportAsFile(`MetaMask ${nickname} Private Key`, plainKey), + }, 'Save as File'), ]) } } @@ -117,6 +123,21 @@ ExportAccountView.prototype.onExportKeyPress = function (event) { if (event.key !== 'Enter') return event.preventDefault() - var input = document.getElementById('exportAccount').value + const input = document.getElementById('exportAccount').value this.props.dispatch(actions.exportAccount(input, this.props.address)) } + +ExportAccountView.prototype.exportAsFile = function (filename, data) { + // source: https://stackoverflow.com/a/33542499 by Ludovic Feltz + const blob = new Blob([data], {type: 'text/csv'}) + if (window.navigator.msSaveOrOpenBlob) { + window.navigator.msSaveBlob(blob, filename) + } else { + const elem = window.document.createElement('a') + elem.href = window.URL.createObjectURL(blob) + elem.download = filename + document.body.appendChild(elem) + elem.click() + document.body.removeChild(elem) + } +} -- cgit From fa1ec5dcd16ba09d31720a42d4015dedde91148c Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Mon, 11 Sep 2017 16:22:20 -0700 Subject: Move function as util function. --- ui/app/components/account-export.js | 18 ++---------------- ui/app/util.js | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 16 deletions(-) (limited to 'ui/app') diff --git a/ui/app/components/account-export.js b/ui/app/components/account-export.js index 5bbdfca39..d438c9ca5 100644 --- a/ui/app/components/account-export.js +++ b/ui/app/components/account-export.js @@ -1,6 +1,7 @@ const Component = require('react').Component const h = require('react-hyperscript') const inherits = require('util').inherits +const exportAsFile = require('../util').exportAsFile const copyToClipboard = require('copy-to-clipboard') const actions = require('../actions') const ethUtil = require('ethereumjs-util') @@ -113,7 +114,7 @@ ExportAccountView.prototype.render = function () { onClick: () => this.props.dispatch(actions.backToAccountDetail(this.props.address)), }, 'Done'), h('button', { - onClick: () => this.exportAsFile(`MetaMask ${nickname} Private Key`, plainKey), + onClick: () => exportAsFile(`MetaMask ${nickname} Private Key`, plainKey), }, 'Save as File'), ]) } @@ -126,18 +127,3 @@ ExportAccountView.prototype.onExportKeyPress = function (event) { const input = document.getElementById('exportAccount').value this.props.dispatch(actions.exportAccount(input, this.props.address)) } - -ExportAccountView.prototype.exportAsFile = function (filename, data) { - // source: https://stackoverflow.com/a/33542499 by Ludovic Feltz - const blob = new Blob([data], {type: 'text/csv'}) - if (window.navigator.msSaveOrOpenBlob) { - window.navigator.msSaveBlob(blob, filename) - } else { - const elem = window.document.createElement('a') - elem.href = window.URL.createObjectURL(blob) - elem.download = filename - document.body.appendChild(elem) - elem.click() - document.body.removeChild(elem) - } -} diff --git a/ui/app/util.js b/ui/app/util.js index ac3f42c6b..1368ebf11 100644 --- a/ui/app/util.js +++ b/ui/app/util.js @@ -36,6 +36,7 @@ module.exports = { valueTable: valueTable, bnTable: bnTable, isHex: isHex, + exportAsFile: exportAsFile, } function valuesFor (obj) { @@ -215,3 +216,18 @@ function readableDate (ms) { function isHex (str) { return Boolean(str.match(/^(0x)?[0-9a-fA-F]+$/)) } + +function exportAsFile (filename, data) { + // source: https://stackoverflow.com/a/33542499 by Ludovic Feltz + const blob = new Blob([data], {type: 'text/csv'}) + if (window.navigator.msSaveOrOpenBlob) { + window.navigator.msSaveBlob(blob, filename) + } else { + const elem = window.document.createElement('a') + elem.href = window.URL.createObjectURL(blob) + elem.download = filename + document.body.appendChild(elem) + elem.click() + document.body.removeChild(elem) + } +} -- cgit From aa021b920942efd8075ca4e89cd92d50a1b21ed0 Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Mon, 11 Sep 2017 16:40:45 -0700 Subject: Add some styling. --- ui/app/components/account-export.js | 3 +++ 1 file changed, 3 insertions(+) (limited to 'ui/app') diff --git a/ui/app/components/account-export.js b/ui/app/components/account-export.js index d438c9ca5..53a7f0fa1 100644 --- a/ui/app/components/account-export.js +++ b/ui/app/components/account-export.js @@ -115,6 +115,9 @@ ExportAccountView.prototype.render = function () { }, 'Done'), h('button', { onClick: () => exportAsFile(`MetaMask ${nickname} Private Key`, plainKey), + stlye: { + marginLeft: '10px', + }, }, 'Save as File'), ]) } -- cgit From e7c1a11b4de100f1966f639c79632a53763a8dac Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Mon, 11 Sep 2017 16:48:02 -0700 Subject: Add ability to save seed words as file. --- ui/app/keychains/hd/create-vault-complete.js | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'ui/app') diff --git a/ui/app/keychains/hd/create-vault-complete.js b/ui/app/keychains/hd/create-vault-complete.js index c32751fff..745990351 100644 --- a/ui/app/keychains/hd/create-vault-complete.js +++ b/ui/app/keychains/hd/create-vault-complete.js @@ -3,6 +3,7 @@ const Component = require('react').Component const connect = require('react-redux').connect const h = require('react-hyperscript') const actions = require('../../actions') +const exportAsFile = require('../../util').exportAsFile module.exports = connect(mapStateToProps)(CreateVaultCompleteScreen) @@ -65,8 +66,17 @@ CreateVaultCompleteScreen.prototype.render = function () { style: { margin: '24px', fontSize: '0.9em', + marginBottom: '10px', }, }, 'I\'ve copied it somewhere safe'), + + h('button.primary', { + onClick: () => exportAsFile(`MetaMask Seed Words`, seed), + style: { + margin: '10px', + fontSize: '0.9em', + }, + }, 'Save Seed Words As File'), ]) ) } -- cgit From 213af0cd6c84366b76a7ba5206fa5a6b79880028 Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Mon, 11 Sep 2017 16:52:35 -0700 Subject: Fix typo. --- ui/app/components/account-export.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'ui/app') diff --git a/ui/app/components/account-export.js b/ui/app/components/account-export.js index 53a7f0fa1..32b103c86 100644 --- a/ui/app/components/account-export.js +++ b/ui/app/components/account-export.js @@ -114,10 +114,10 @@ ExportAccountView.prototype.render = function () { onClick: () => this.props.dispatch(actions.backToAccountDetail(this.props.address)), }, 'Done'), h('button', { - onClick: () => exportAsFile(`MetaMask ${nickname} Private Key`, plainKey), - stlye: { + style: { marginLeft: '10px', }, + onClick: () => exportAsFile(`MetaMask ${nickname} Private Key`, plainKey), }, 'Save as File'), ]) } -- cgit From ad14e9338d2e08b0fd0e371e7a81e20f8f9e90f7 Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Tue, 12 Sep 2017 09:34:48 -0700 Subject: Convert state logs into a download. --- ui/app/config.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'ui/app') diff --git a/ui/app/config.js b/ui/app/config.js index 62785c49b..d64088ccb 100644 --- a/ui/app/config.js +++ b/ui/app/config.js @@ -5,7 +5,8 @@ const connect = require('react-redux').connect const actions = require('./actions') const currencies = require('./conversion.json').rows const validUrl = require('valid-url') -const copyToClipboard = require('copy-to-clipboard') +const exportAsFile = require('./util').exportAsFile + module.exports = connect(mapStateToProps)(ConfigScreen) @@ -110,9 +111,9 @@ ConfigScreen.prototype.render = function () { alignSelf: 'center', }, onClick (event) { - copyToClipboard(window.logState()) + exportAsFile('MetaMask State Logs', window.logState()) }, - }, 'Copy State Logs'), + }, 'Download State Logs'), ]), h('hr.horizontal-line'), -- cgit