Merge pull request #615 from MetaMask/ModularFiatBalance

Add fiat conversion to tx confirmation view
feature/default_network_editable
Kevin Serrano 8 years ago committed by GitHub
commit 80847739b2
  1. 1
      CHANGELOG.md
  2. 2
      development/states.js
  3. 94
      development/states/pending-tx-send-coin.json
  4. 4
      ui/app/account-detail.js
  5. 4
      ui/app/accounts/account-list-item.js
  6. 15
      ui/app/app.js
  7. 140
      ui/app/components/account-eth-balance.js
  8. 25
      ui/app/components/eth-balance.js
  9. 71
      ui/app/components/fiat-value.js
  10. 1
      ui/app/components/network.js
  11. 11
      ui/app/components/pending-tx-details.js
  12. 8
      ui/app/components/tooltip.js
  13. 1
      ui/app/components/transaction-list-item.js
  14. 5
      ui/app/send.js

@ -2,6 +2,7 @@
## Current Master
- Add fiat conversion values to more views.
- On fresh install, open a new tab with the MetaMask Introduction video.
- Block negative values from transactions.
- Fixed a memory leak.

File diff suppressed because one or more lines are too long

@ -1 +1,93 @@
{"metamask":{"isInitialized":true,"isUnlocked":true,"currentDomain":"example.com","rpcTarget":"https://rawtestrpc.metamask.io/","identities":{"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825":{"name":"Wallet 1","address":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","mayBeFauceting":false},"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb":{"name":"Wallet 2","address":"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb","mayBeFauceting":false},"0x2f8d4a878cfa04a6e60d46362f5644deab66572d":{"name":"Wallet 3","address":"0x2f8d4a878cfa04a6e60d46362f5644deab66572d","mayBeFauceting":false}},"unconfTxs":{"1467868023090690":{"id":1467868023090690,"txParams":{"data":"0xa9059cbb0000000000000000000000008deb4d106090c3eb8f1950f727e87c4f884fb06f0000000000000000000000000000000000000000000000000000000000000064","from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","value":"0x16345785d8a0000","to":"0xbeb0ed3034c4155f3d16a64a5c5e7c8d4ea9e9c9","origin":"MetaMask","metamaskId":1467868023090690,"metamaskNetworkId":"2"},"time":1467868023090,"status":"unconfirmed","containsDelegateCall":false}},"accounts":{"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825":{"code":"0x","balance":"0x38326dc32cf80800","nonce":"0x10000c","address":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825"},"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb":{"code":"0x","balance":"0x15e578bd8e9c8000","nonce":"0x100000","address":"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb"},"0x2f8d4a878cfa04a6e60d46362f5644deab66572d":{"code":"0x","nonce":"0x100000","balance":"0x2386f26fc10000","address":"0x2f8d4a878cfa04a6e60d46362f5644deab66572d"}},"transactions":[],"selectedAddress":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","network":"2","seedWords":null,"isConfirmed":true,"unconfMsgs":{},"messages":[],"provider":{"type":"testnet"},"selectedAccount":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825"},"appState":{"menuOpen":false,"currentView":{"name":"confTx","context":0},"accountDetail":{"subview":"transactions"},"currentDomain":"extensions","transForward":true,"isLoading":false,"warning":null},"identities":{}}
{
"metamask": {
"currentFiat": "USD",
"conversionRate": 11.06608791,
"conversionDate": 1470421024,
"isInitialized": true,
"isInitialized": true,
"isUnlocked": true,
"isEthConfirmed": false,
"currentDomain": "example.com",
"rpcTarget": "https://rawtestrpc.metamask.io/",
"identities": {
"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825": {
"name": "Wallet 1",
"address": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825",
"mayBeFauceting": false
},
"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb": {
"name": "Wallet 2",
"address": "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb",
"mayBeFauceting": false
},
"0x2f8d4a878cfa04a6e60d46362f5644deab66572d": {
"name": "Wallet 3",
"address": "0x2f8d4a878cfa04a6e60d46362f5644deab66572d",
"mayBeFauceting": false
}
},
"unconfTxs": {
"1473207765149885": {
"id": 1473207765149885,
"txParams": {
"from": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825",
"value": "0x16345785d8a0000",
"to": "0xC5b8dBAc4c1d3F152cDeb400E2313F309c410aCb",
"origin": "MetaMask",
"metamaskId": 1473207765149885,
"metamaskNetworkId": "1473186153102"
},
"time": 1473207765149,
"status": "unconfirmed",
"containsDelegateCall": false,
"estimatedGas": "0x5208"
}
},
"accounts": {
"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825": {
"code": "0x",
"balance": "0x38326dc32cf80800",
"nonce": "0x10000c",
"address": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825"
},
"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb": {
"code": "0x",
"balance": "0x15e578bd8e9c8000",
"nonce": "0x100000",
"address": "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb"
},
"0x2f8d4a878cfa04a6e60d46362f5644deab66572d": {
"code": "0x",
"nonce": "0x100000",
"balance": "0x2386f26fc10000",
"address": "0x2f8d4a878cfa04a6e60d46362f5644deab66572d"
}
},
"transactions": [],
"selectedAddress": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825",
"network": "2",
"seedWords": null,
"isConfirmed": true,
"unconfMsgs": {},
"messages": [],
"provider": {
"type": "testnet"
},
"selectedAccount": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825"
},
"appState": {
"menuOpen": false,
"currentView": {
"name": "confTx",
"context": 0
},
"accountDetail": {
"subview": "transactions"
},
"currentDomain": "extensions",
"transForward": true,
"isLoading": false,
"warning": null
},
"identities": {}
}

@ -10,7 +10,7 @@ const ReactCSSTransitionGroup = require('react-addons-css-transition-group')
const valuesFor = require('./util').valuesFor
const Identicon = require('./components/identicon')
const AccountEtherBalance = require('./components/account-eth-balance')
const EthBalance = require('./components/eth-balance')
const TransactionList = require('./components/transaction-list')
const ExportAccountView = require('./components/account-export')
const ethUtil = require('ethereumjs-util')
@ -168,7 +168,7 @@ AccountDetailScreen.prototype.render = function () {
},
}, [
h(AccountEtherBalance, {
h(EthBalance, {
value: account && account.balance,
style: {
lineHeight: '7px',

@ -3,7 +3,7 @@ const h = require('react-hyperscript')
const inherits = require('util').inherits
const ethUtil = require('ethereumjs-util')
const AccountEtherBalance = require('../components/account-eth-balance')
const EthBalance = require('../components/eth-balance')
const CopyButton = require('../components/copyButton')
const Identicon = require('../components/identicon')
@ -50,7 +50,7 @@ NewComponent.prototype.render = function () {
textOverflow: 'ellipsis',
},
}, ethUtil.toChecksumAddress(identity.address)),
h(AccountEtherBalance, {
h(EthBalance, {
value: account.balance,
style: {
lineHeight: '7px',

@ -245,7 +245,7 @@ App.prototype.renderNetworkDropdown = function () {
label: 'Localhost 8545',
closeMenu: () => this.setState({ isNetworkMenuOpen: false }),
action: () => props.dispatch(actions.setRpcTarget('http://localhost:8545')),
icon: h('i.fa.fa-question-circle.fa-lg', { ariaHidden: true }),
icon: h('i.fa.fa-question-circle.fa-lg'),
activeNetworkRender: props.provider.rpcTarget,
}),
@ -253,7 +253,7 @@ App.prototype.renderNetworkDropdown = function () {
label: 'Custom RPC',
closeMenu: () => this.setState({ isNetworkMenuOpen: false }),
action: () => this.props.dispatch(actions.showConfigPage()),
icon: h('i.fa.fa-question-circle.fa-lg', { ariaHidden: true }),
icon: h('i.fa.fa-question-circle.fa-lg'),
}),
this.renderCustomOption(props.provider.rpcTarget),
@ -289,21 +289,21 @@ App.prototype.renderDropdown = function () {
label: 'Settings',
closeMenu: () => this.setState({ isMainMenuOpen: !isOpen }),
action: () => this.props.dispatch(actions.showConfigPage()),
icon: h('i.fa.fa-gear.fa-lg', { ariaHidden: true }),
icon: h('i.fa.fa-gear.fa-lg'),
}),
h(DropMenuItem, {
label: 'Lock',
closeMenu: () => this.setState({ isMainMenuOpen: !isOpen }),
action: () => this.props.dispatch(actions.lockMetamask()),
icon: h('i.fa.fa-lock.fa-lg', { ariaHidden: true }),
icon: h('i.fa.fa-lock.fa-lg'),
}),
h(DropMenuItem, {
label: 'Help',
closeMenu: () => this.setState({ isMainMenuOpen: !isOpen }),
action: () => this.props.dispatch(actions.showInfoPage()),
icon: h('i.fa.fa-question.fa-lg', { ariaHidden: true }),
icon: h('i.fa.fa-question.fa-lg'),
}),
])
}
@ -312,7 +312,6 @@ App.prototype.renderBackButton = function (style, justArrow = false) {
return (
h('.flex-row', {
key: 'leftArrow',
transForward: false,
style: style,
onClick: () => props.dispatch(actions.goBackToInitView()),
}, [
@ -515,14 +514,14 @@ App.prototype.renderCustomOption = function (rpcTarget) {
label: 'Custom RPC',
closeMenu: () => this.setState({ isNetworkMenuOpen: false }),
action: () => this.props.dispatch(actions.showConfigPage()),
icon: h('i.fa.fa-question-circle.fa-lg', { ariaHidden: true }),
icon: h('i.fa.fa-question-circle.fa-lg'),
})
default:
return h(DropMenuItem, {
label: `${rpcTarget}`,
closeMenu: () => this.setState({ isNetworkMenuOpen: false }),
icon: h('i.fa.fa-question-circle.fa-lg', { ariaHidden: true }),
icon: h('i.fa.fa-question-circle.fa-lg'),
activeNetworkRender: 'custom',
})
}

@ -1,140 +0,0 @@
const Component = require('react').Component
const h = require('react-hyperscript')
const inherits = require('util').inherits
const connect = require('react-redux').connect
const formatBalance = require('../util').formatBalance
const generateBalanceObject = require('../util').generateBalanceObject
const Tooltip = require('./tooltip.js')
module.exports = connect(mapStateToProps)(EthBalanceComponent)
function mapStateToProps (state) {
return {
conversionRate: state.metamask.conversionRate,
conversionDate: state.metamask.conversionDate,
currentFiat: state.metamask.currentFiat,
}
}
inherits(EthBalanceComponent, Component)
function EthBalanceComponent () {
Component.call(this)
}
EthBalanceComponent.prototype.render = function () {
var state = this.props
var style = state.style
const value = formatBalance(state.value, 6)
var width = state.width
return (
h('.ether-balance', {
style: style,
}, [
h('.ether-balance-amount', {
style: {
display: 'inline',
width: width,
},
}, this.renderBalance(value, state)),
])
)
}
EthBalanceComponent.prototype.renderBalance = function (value, state) {
if (value === 'None') return value
var balanceObj = generateBalanceObject(value, state.shorten ? 1 : 3)
var balance, fiatDisplayNumber, fiatTooltipNumber
var splitBalance = value.split(' ')
var ethNumber = splitBalance[0]
var ethSuffix = splitBalance[1]
if (state.conversionRate !== 0) {
fiatTooltipNumber = Number(splitBalance[0]) * state.conversionRate
fiatDisplayNumber = fiatTooltipNumber.toFixed(2)
} else {
fiatDisplayNumber = 'N/A'
}
var fiatSuffix = state.currentFiat
if (state.shorten) {
balance = balanceObj.shortBalance
} else {
balance = balanceObj.balance
}
var label = balanceObj.label
return (
h('.flex-column', [
h(Tooltip, {
position: 'bottom',
title: `${ethNumber} ${ethSuffix}`,
}, [
h('.flex-row', {
style: {
alignItems: 'flex-end',
lineHeight: '13px',
fontFamily: 'Montserrat Light',
textRendering: 'geometricPrecision',
marginBottom: '5px',
},
}, [
h('div', {
style: {
width: '100%',
textAlign: 'right',
},
}, balance),
h('div', {
style: {
color: '#AEAEAE',
marginLeft: '5px',
},
}, label),
]),
]),
h(Tooltip, {
position: 'bottom',
title: `${fiatTooltipNumber} ${fiatSuffix}`,
}, [
fiatDisplay(fiatDisplayNumber, fiatSuffix),
]),
])
)
}
function fiatDisplay (fiatDisplayNumber, fiatSuffix) {
if (fiatDisplayNumber !== 'N/A') {
return h('.flex-row', {
style: {
alignItems: 'flex-end',
lineHeight: '13px',
fontFamily: 'Montserrat Light',
textRendering: 'geometricPrecision',
},
}, [
h('div', {
style: {
width: '100%',
textAlign: 'right',
fontSize: '12px',
color: '#333333',
},
}, fiatDisplayNumber),
h('div', {
style: {
color: '#AEAEAE',
marginLeft: '5px',
fontSize: '12px',
},
}, fiatSuffix),
])
} else {
return h('div')
}
}

@ -4,6 +4,7 @@ const inherits = require('util').inherits
const formatBalance = require('../util').formatBalance
const generateBalanceObject = require('../util').generateBalanceObject
const Tooltip = require('./tooltip.js')
const FiatValue = require('./fiat-value.js')
module.exports = EthBalanceComponent
@ -13,11 +14,11 @@ function EthBalanceComponent () {
}
EthBalanceComponent.prototype.render = function () {
var state = this.props
var style = state.style
var props = this.props
var style = props.style
var needsParse = this.props.needsParse !== undefined ? this.props.needsParse : true
const value = formatBalance(state.value, 6, needsParse)
var width = state.width
const value = formatBalance(props.value, 6, needsParse)
var width = props.width
return (
@ -35,15 +36,16 @@ EthBalanceComponent.prototype.render = function () {
)
}
EthBalanceComponent.prototype.renderBalance = function (value) {
var state = this.props
var props = this.props
if (value === 'None') return value
var balanceObj = generateBalanceObject(value, state.shorten ? 1 : 3)
var balanceObj = generateBalanceObject(value, props.shorten ? 1 : 3)
var balance
var splitBalance = value.split(' ')
var ethNumber = splitBalance[0]
var ethSuffix = splitBalance[1]
const showFiat = 'showFiat' in props ? props.showFiat : true
if (state.shorten) {
if (props.shorten) {
balance = balanceObj.shortBalance
} else {
balance = balanceObj.balance
@ -55,8 +57,8 @@ EthBalanceComponent.prototype.renderBalance = function (value) {
h(Tooltip, {
position: 'bottom',
title: `${ethNumber} ${ethSuffix}`,
}, [
h('.flex-column', {
}, h('div.flex-column', [
h('.flex-row', {
style: {
alignItems: 'flex-end',
lineHeight: '13px',
@ -74,9 +76,12 @@ EthBalanceComponent.prototype.renderBalance = function (value) {
style: {
color: ' #AEAEAE',
fontSize: '12px',
marginLeft: '5px',
},
}, label),
]),
])
showFiat ? h(FiatValue, { value: props.value }) : null,
]))
)
}

@ -0,0 +1,71 @@
const Component = require('react').Component
const h = require('react-hyperscript')
const inherits = require('util').inherits
const connect = require('react-redux').connect
const formatBalance = require('../util').formatBalance
module.exports = connect(mapStateToProps)(FiatValue)
function mapStateToProps (state) {
return {
conversionRate: state.metamask.conversionRate,
currentFiat: state.metamask.currentFiat,
}
}
inherits(FiatValue, Component)
function FiatValue () {
Component.call(this)
}
FiatValue.prototype.render = function () {
const props = this.props
const value = formatBalance(props.value, 6)
if (value === 'None') return value
var fiatDisplayNumber, fiatTooltipNumber
var splitBalance = value.split(' ')
if (props.conversionRate !== 0) {
fiatTooltipNumber = Number(splitBalance[0]) * props.conversionRate
fiatDisplayNumber = fiatTooltipNumber.toFixed(2)
} else {
fiatDisplayNumber = 'N/A'
fiatTooltipNumber = 'Unknown'
}
var fiatSuffix = props.currentFiat
return fiatDisplay(fiatDisplayNumber, fiatSuffix)
}
function fiatDisplay (fiatDisplayNumber, fiatSuffix) {
if (fiatDisplayNumber !== 'N/A') {
return h('.flex-row', {
style: {
alignItems: 'flex-end',
lineHeight: '13px',
fontFamily: 'Montserrat Light',
textRendering: 'geometricPrecision',
},
}, [
h('div', {
style: {
width: '100%',
textAlign: 'right',
fontSize: '12px',
color: '#333333',
},
}, fiatDisplayNumber),
h('div', {
style: {
color: '#AEAEAE',
marginLeft: '5px',
fontSize: '12px',
},
}, fiatSuffix),
])
} else {
return h('div')
}
}

@ -75,7 +75,6 @@ Network.prototype.render = function () {
default:
return h('.network-indicator', [
h('i.fa.fa-question-circle.fa-lg', {
ariaHidden: true,
style: {
margin: '10px',
color: 'rgb(125, 128, 130)',

@ -4,9 +4,8 @@ const inherits = require('util').inherits
const carratInline = require('fs').readFileSync('./images/forward-carrat.svg', 'utf8')
const MiniAccountPanel = require('./mini-account-panel')
const EtherBalance = require('./eth-balance')
const EthBalance = require('./eth-balance')
const addressSummary = require('../util').addressSummary
const formatBalance = require('../util').formatBalance
const nameForAddress = require('../../lib/contract-namer')
const ethUtil = require('ethereumjs-util')
const BN = ethUtil.BN
@ -70,7 +69,7 @@ PTXP.render = function () {
fontFamily: 'Montserrat Light, Montserrat, sans-serif',
},
}, [
h(EtherBalance, {
h(EthBalance, {
value: balance,
inline: true,
labelColor: '#F7861C',
@ -107,12 +106,12 @@ PTXP.render = function () {
h('.row', [
h('.cell.label', 'Amount'),
h('.cell.value', formatBalance(txParams.value)),
h(EthBalance, { value: txParams.value }),
]),
h('.cell.row', [
h('.cell.label', 'Max Transaction Fee'),
h('.cell.value', formatBalance(txFee.toString(16))),
h(EthBalance, { value: txFee.toString(16) }),
]),
h('.cell.row', {
@ -129,7 +128,7 @@ PTXP.render = function () {
alignItems: 'center',
},
}, [
h(EtherBalance, {
h(EthBalance, {
value: maxCost.toString(16),
inline: true,
labelColor: 'black',

@ -11,12 +11,14 @@ function Tooltip () {
}
Tooltip.prototype.render = function () {
const props = this.props
const { position, title, children } = props
return h(ReactTooltip, {
position: props.position ? props.position : 'left',
title: props.title,
position: position || 'left',
title,
fixed: false,
}, props.children)
}, children)
}

@ -77,6 +77,7 @@ TransactionListItem.prototype.render = function () {
value: txParams.value,
width: '55px',
shorten: true,
showFiat: false,
style: {fontSize: '15px'},
}) : h('.flex-column'),
])

@ -7,7 +7,7 @@ const actions = require('./actions')
const util = require('./util')
const numericBalance = require('./util').numericBalance
const addressSummary = require('./util').addressSummary
const EtherBalance = require('./components/eth-balance')
const EthBalance = require('./components/eth-balance')
const ethUtil = require('ethereumjs-util')
module.exports = connect(mapStateToProps)(SendTransactionScreen)
@ -107,8 +107,7 @@ SendTransactionScreen.prototype.render = function () {
// balance
h('.flex-row.flex-center', [
// h('div', formatBalance(account && account.balance)),
h(EtherBalance, {
h(EthBalance, {
value: account && account.balance,
}),

Loading…
Cancel
Save