aboutsummaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authorkumavis <aaron@kumavis.me>2017-09-13 02:51:22 +0800
committerkumavis <aaron@kumavis.me>2017-09-13 02:51:22 +0800
commit114dae5f8070e47409a01981f2aeff96827cbf41 (patch)
treebe37b3fd47a9f95c27d812d1d97b3858fe64a469 /ui
parent8545453a9d58d7a54c10beef52e38107ed937117 (diff)
parentcafebb6417331d9d0a0a83fdc1cc4fdb04d0a5ec (diff)
downloadtangerine-wallet-browser-114dae5f8070e47409a01981f2aeff96827cbf41.tar.gz
tangerine-wallet-browser-114dae5f8070e47409a01981f2aeff96827cbf41.tar.zst
tangerine-wallet-browser-114dae5f8070e47409a01981f2aeff96827cbf41.zip
Merge branch 'master' of github.com:MetaMask/metamask-extension into filter-leak-fix3
Diffstat (limited to 'ui')
-rw-r--r--ui/app/actions.js11
-rw-r--r--ui/app/components/account-export.js28
-rw-r--r--ui/app/components/pending-tx.js36
-rw-r--r--ui/app/conf-tx.js10
-rw-r--r--ui/app/config.js7
-rw-r--r--ui/app/keychains/hd/create-vault-complete.js10
-rw-r--r--ui/app/util.js16
7 files changed, 91 insertions, 27 deletions
diff --git a/ui/app/actions.js b/ui/app/actions.js
index eebe65ba2..e793e6a21 100644
--- a/ui/app/actions.js
+++ b/ui/app/actions.js
@@ -104,6 +104,7 @@ var actions = {
txError: txError,
nextTx: nextTx,
previousTx: previousTx,
+ cancelAllTx: cancelAllTx,
viewPendingTx: viewPendingTx,
VIEW_PENDING_TX: 'VIEW_PENDING_TX',
// app messages
@@ -457,6 +458,16 @@ function cancelTx (txData) {
}
}
+function cancelAllTx (txsData) {
+ return (dispatch) => {
+ txsData.forEach((txData, i) => {
+ background.cancelTransaction(txData.id, () => {
+ dispatch(actions.completedTx(txData.id))
+ i === txsData.length - 1 ? dispatch(actions.goHome()) : null
+ })
+ })
+ }
+}
//
// initialize screen
//
diff --git a/ui/app/components/account-export.js b/ui/app/components/account-export.js
index 330f73805..32b103c86 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')
@@ -20,20 +21,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 +91,8 @@ ExportAccountView.prototype.render = function () {
}
if (accountExported) {
+ const plainKey = ethUtil.stripHexPrefix(accountDetail.privateKey)
+
return h('div.privateKey', {
style: {
margin: '0 20px',
@@ -105,10 +109,16 @@ 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', {
+ style: {
+ marginLeft: '10px',
+ },
+ onClick: () => exportAsFile(`MetaMask ${nickname} Private Key`, plainKey),
+ }, 'Save as File'),
])
}
}
@@ -117,6 +127,6 @@ 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))
}
diff --git a/ui/app/components/pending-tx.js b/ui/app/components/pending-tx.js
index 5324ccd64..3e53d47f9 100644
--- a/ui/app/components/pending-tx.js
+++ b/ui/app/components/pending-tx.js
@@ -66,6 +66,8 @@ 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 = []
@@ -297,14 +299,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,18 +306,30 @@ 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,
}, 'Reject'),
]),
+ showRejectAll ? 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'),
+ ]) : null,
]),
])
)
diff --git a/ui/app/conf-tx.js b/ui/app/conf-tx.js
index 34727ff78..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,10 +103,12 @@ ConfirmTxScreen.prototype.render = function () {
conversionRate,
currentCurrency,
blockGasLimit,
+ unconfTxListLength,
// Actions
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),
@@ -151,6 +155,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
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'),
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'),
])
)
}
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)
+ }
+}