aboutsummaryrefslogtreecommitdiffstats
path: root/ui/app/components
diff options
context:
space:
mode:
Diffstat (limited to 'ui/app/components')
-rw-r--r--ui/app/components/account-dropdowns.js21
-rw-r--r--ui/app/components/account-export.js28
-rw-r--r--ui/app/components/dropdown.js2
-rw-r--r--ui/app/components/network.js11
-rw-r--r--ui/app/components/pending-tx.js107
-rw-r--r--ui/app/components/tooltip.js2
-rw-r--r--ui/app/components/transaction-list-item-icon.js2
-rw-r--r--ui/app/components/transaction-list-item.js2
8 files changed, 115 insertions, 60 deletions
diff --git a/ui/app/components/account-dropdowns.js b/ui/app/components/account-dropdowns.js
index 7c24e70bd..b087a40d4 100644
--- a/ui/app/components/account-dropdowns.js
+++ b/ui/app/components/account-dropdowns.js
@@ -22,12 +22,19 @@ class AccountDropdowns extends Component {
}
renderAccounts () {
- const { identities, selected } = this.props
+ const { identities, selected, keyrings } = this.props
return Object.keys(identities).map((key, index) => {
const identity = identities[key]
const isSelected = identity.address === selected
+ const simpleAddress = identity.address.substring(2).toLowerCase()
+
+ const keyring = keyrings.find((kr) => {
+ return kr.accounts.includes(simpleAddress) ||
+ kr.accounts.includes(identity.address)
+ })
+
return h(
DropdownMenuItem,
{
@@ -51,6 +58,7 @@ class AccountDropdowns extends Component {
},
},
),
+ this.indicateIfLoose(keyring),
h('span', {
style: {
marginLeft: '20px',
@@ -67,6 +75,14 @@ class AccountDropdowns extends Component {
})
}
+ indicateIfLoose (keyring) {
+ try { // Sometimes keyrings aren't loaded yet:
+ const type = keyring.type
+ const isLoose = type !== 'HD Key Tree'
+ return isLoose ? h('.keyring-label', 'LOOSE') : null
+ } catch (e) { return }
+ }
+
renderAccountSelector () {
const { actions } = this.props
const { accountSelectorActive } = this.state
@@ -145,6 +161,8 @@ class AccountDropdowns extends Component {
)
}
+
+
renderAccountOptions () {
const { actions } = this.props
const { optionsMenuActive } = this.state
@@ -278,6 +296,7 @@ AccountDropdowns.defaultProps = {
AccountDropdowns.propTypes = {
identities: PropTypes.objectOf(PropTypes.object),
selected: PropTypes.string,
+ keyrings: PropTypes.array,
}
const mapDispatchToProps = (dispatch) => {
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/dropdown.js b/ui/app/components/dropdown.js
index 34c7149ee..73710acc2 100644
--- a/ui/app/components/dropdown.js
+++ b/ui/app/components/dropdown.js
@@ -32,7 +32,7 @@ class Dropdown extends Component {
'style',
`
li.dropdown-menu-item:hover { color:rgb(225, 225, 225); }
- li.dropdown-menu-item { color: rgb(185, 185, 185); }
+ li.dropdown-menu-item { color: rgb(185, 185, 185); position: relative }
`
),
...children,
diff --git a/ui/app/components/network.js b/ui/app/components/network.js
index 698a0bbb9..0dbe37cdd 100644
--- a/ui/app/components/network.js
+++ b/ui/app/components/network.js
@@ -22,7 +22,7 @@ Network.prototype.render = function () {
let iconName, hoverText
if (networkNumber === 'loading') {
- return h('span', {
+ return h('span.pointer', {
style: {
display: 'flex',
alignItems: 'center',
@@ -37,7 +37,7 @@ Network.prototype.render = function () {
},
src: 'images/loading.svg',
}),
- h('i.fa.fa-sort-desc'),
+ h('i.fa.fa-caret-down'),
])
} else if (providerName === 'mainnet') {
hoverText = 'Main Ethereum Network'
@@ -73,7 +73,8 @@ Network.prototype.render = function () {
style: {
color: '#039396',
}},
- 'Ethereum Main Net'),
+ 'Main Network'),
+ h('i.fa.fa-caret-down.fa-lg'),
])
case 'ropsten-test-network':
return h('.network-indicator', [
@@ -83,6 +84,7 @@ Network.prototype.render = function () {
color: '#ff6666',
}},
'Ropsten Test Net'),
+ h('i.fa.fa-caret-down.fa-lg'),
])
case 'kovan-test-network':
return h('.network-indicator', [
@@ -92,6 +94,7 @@ Network.prototype.render = function () {
color: '#690496',
}},
'Kovan Test Net'),
+ h('i.fa.fa-caret-down.fa-lg'),
])
case 'rinkeby-test-network':
return h('.network-indicator', [
@@ -101,6 +104,7 @@ Network.prototype.render = function () {
color: '#e7a218',
}},
'Rinkeby Test Net'),
+ h('i.fa.fa-caret-down.fa-lg'),
])
default:
return h('.network-indicator', [
@@ -116,6 +120,7 @@ Network.prototype.render = function () {
color: '#AEAEAE',
}},
'Private Network'),
+ h('i.fa.fa-caret-down.fa-lg'),
])
}
})(),
diff --git a/ui/app/components/pending-tx.js b/ui/app/components/pending-tx.js
index 5324ccd64..6f8c19a3c 100644
--- a/ui/app/components/pending-tx.js
+++ b/ui/app/components/pending-tx.js
@@ -33,7 +33,7 @@ function PendingTx () {
PendingTx.prototype.render = function () {
const props = this.props
- const { currentCurrency, blockGasLimit } = props
+ const { currentCurrency, blockGasLimit, computedBalances } = props
const conversionRate = props.conversionRate
const txMeta = this.gatherTxMeta()
@@ -42,8 +42,8 @@ PendingTx.prototype.render = function () {
// Account Details
const address = txParams.from || props.selectedAddress
const identity = props.identities[address] || { address: address }
- const account = props.accounts[address]
- const balance = account ? account.balance : '0x0'
+ const account = computedBalances[address]
+ const balance = account ? account.ethBalance : '0x0'
// recipient check
const isValidAddress = !txParams.to || util.isValidAddress(txParams.to)
@@ -52,7 +52,9 @@ PendingTx.prototype.render = function () {
const gas = txParams.gas
const gasBn = hexToBn(gas)
const gasLimit = new BN(parseInt(blockGasLimit))
- const safeGasLimit = this.bnMultiplyByFraction(gasLimit, 19, 20).toString(10)
+ const safeGasLimitBN = this.bnMultiplyByFraction(gasLimit, 19, 20)
+ const saferGasLimitBN = this.bnMultiplyByFraction(gasLimit, 18, 20)
+ const safeGasLimit = safeGasLimitBN.toString(10)
// Gas Price
const gasPrice = txParams.gasPrice || MIN_GAS_PRICE_BN.toString(16)
@@ -66,6 +68,10 @@ PendingTx.prototype.render = function () {
const balanceBn = hexToBn(balance)
const insufficientBalance = balanceBn.lt(maxCost)
+ const dangerousGasLimit = gasBn.gte(saferGasLimitBN)
+ const gasLimitSpecified = txMeta.gasLimitSpecified
+ const buyDisabled = insufficientBalance || !this.state.valid || !isValidAddress || this.state.submitting
+ const showRejectAll = props.unconfTxListLength > 1
this.inputs = []
@@ -261,33 +267,44 @@ PendingTx.prototype.render = function () {
text-transform: uppercase;
}
`),
+ h('.cell.row', {
+ style: {
+ textAlign: 'center',
+ },
+ }, [
+ txMeta.simulationFails ?
+ h('.error', {
+ style: {
+ fontSize: '0.9em',
+ },
+ }, 'Transaction Error. Exception thrown in contract code.')
+ : null,
- txMeta.simulationFails ?
- h('.error', {
- style: {
- marginLeft: 50,
- fontSize: '0.9em',
- },
- }, 'Transaction Error. Exception thrown in contract code.')
- : null,
+ !isValidAddress ?
+ h('.error', {
+ style: {
+ fontSize: '0.9em',
+ },
+ }, 'Recipient address is invalid. Sending this transaction will result in a loss of ETH.')
+ : 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: {
+ fontSize: '0.9em',
+ },
+ }, 'Insufficient balance for transaction')
+ : null,
+
+ (dangerousGasLimit && !gasLimitSpecified) ?
+ h('span.error', {
+ style: {
+ fontSize: '0.9em',
+ },
+ }, 'Gas limit set dangerously high. Approving this transaction is likely to fail.')
+ : null,
+ ]),
- insufficientBalance ?
- h('span.error', {
- style: {
- marginLeft: 50,
- fontSize: '0.9em',
- },
- }, 'Insufficient balance for transaction')
- : null,
// send + cancel
h('.flex-row.flex-space-around.conf-buttons', {
@@ -297,14 +314,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 +321,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/components/tooltip.js b/ui/app/components/tooltip.js
index edbc074bb..efab2c497 100644
--- a/ui/app/components/tooltip.js
+++ b/ui/app/components/tooltip.js
@@ -17,6 +17,6 @@ Tooltip.prototype.render = function () {
return h(ReactTooltip, {
position: position || 'left',
title,
- fixed: false,
+ fixed: true,
}, children)
}
diff --git a/ui/app/components/transaction-list-item-icon.js b/ui/app/components/transaction-list-item-icon.js
index 431054340..f442b05af 100644
--- a/ui/app/components/transaction-list-item-icon.js
+++ b/ui/app/components/transaction-list-item-icon.js
@@ -35,7 +35,7 @@ TransactionIcon.prototype.render = function () {
case 'submitted':
return h(Tooltip, {
title: 'Pending',
- position: 'bottom',
+ position: 'right',
}, [
h('i.fa.fa-ellipsis-h', {
style: {
diff --git a/ui/app/components/transaction-list-item.js b/ui/app/components/transaction-list-item.js
index 5d5d0bcc5..0e5c0b5a3 100644
--- a/ui/app/components/transaction-list-item.js
+++ b/ui/app/components/transaction-list-item.js
@@ -65,7 +65,7 @@ TransactionListItem.prototype.render = function () {
h(Tooltip, {
title: 'Transaction Number',
- position: 'bottom',
+ position: 'right',
}, [
h('span', {
style: {