aboutsummaryrefslogtreecommitdiffstats
path: root/ui/app/components
diff options
context:
space:
mode:
Diffstat (limited to 'ui/app/components')
-rw-r--r--ui/app/components/account-export.js2
-rw-r--r--ui/app/components/balance.js89
-rw-r--r--ui/app/components/identicon.js14
-rw-r--r--ui/app/components/loading.js5
-rw-r--r--ui/app/components/tab-bar.js1
-rw-r--r--ui/app/components/token-cell.js46
-rw-r--r--ui/app/components/token-list.js147
-rw-r--r--ui/app/components/transaction-list.js11
8 files changed, 296 insertions, 19 deletions
diff --git a/ui/app/components/account-export.js b/ui/app/components/account-export.js
index 888196c5d..394d878f7 100644
--- a/ui/app/components/account-export.js
+++ b/ui/app/components/account-export.js
@@ -20,8 +20,6 @@ function mapStateToProps (state) {
}
ExportAccountView.prototype.render = function () {
- console.log('EXPORT VIEW')
- console.dir(this.props)
var state = this.props
var accountDetail = state.accountDetail
diff --git a/ui/app/components/balance.js b/ui/app/components/balance.js
new file mode 100644
index 000000000..57ca84564
--- /dev/null
+++ b/ui/app/components/balance.js
@@ -0,0 +1,89 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+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
+
+inherits(EthBalanceComponent, Component)
+function EthBalanceComponent () {
+ Component.call(this)
+}
+
+EthBalanceComponent.prototype.render = function () {
+ var props = this.props
+ let { value } = props
+ var style = props.style
+ var needsParse = this.props.needsParse !== undefined ? this.props.needsParse : true
+ value = value ? formatBalance(value, 6, needsParse) : '...'
+ var width = props.width
+
+ return (
+
+ h('.ether-balance.ether-balance-amount', {
+ style: style,
+ }, [
+ h('div', {
+ style: {
+ display: 'inline',
+ width: width,
+ },
+ }, this.renderBalance(value)),
+ ])
+
+ )
+}
+EthBalanceComponent.prototype.renderBalance = function (value) {
+ var props = this.props
+ if (value === 'None') return value
+ if (value === '...') return value
+ 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 (props.shorten) {
+ balance = balanceObj.shortBalance
+ } else {
+ balance = balanceObj.balance
+ }
+
+ var label = balanceObj.label
+
+ return (
+ h(Tooltip, {
+ position: 'bottom',
+ title: `${ethNumber} ${ethSuffix}`,
+ }, h('div.flex-column', [
+ h('.flex-row', {
+ style: {
+ alignItems: 'flex-end',
+ lineHeight: '13px',
+ fontFamily: 'Montserrat Light',
+ textRendering: 'geometricPrecision',
+ },
+ }, [
+ h('div', {
+ style: {
+ width: '100%',
+ textAlign: 'right',
+ },
+ }, this.props.incoming ? `+${balance}` : balance),
+ h('div', {
+ style: {
+ color: ' #AEAEAE',
+ fontSize: '12px',
+ marginLeft: '5px',
+ },
+ }, label),
+ ]),
+
+ showFiat ? h(FiatValue, { value: props.value }) : null,
+ ]))
+ )
+}
diff --git a/ui/app/components/identicon.js b/ui/app/components/identicon.js
index 9de854b54..c754bc6ba 100644
--- a/ui/app/components/identicon.js
+++ b/ui/app/components/identicon.js
@@ -23,7 +23,9 @@ IdenticonComponent.prototype.render = function () {
h('div', {
key: 'identicon-' + this.props.address,
style: {
- display: 'inline-block',
+ display: 'flex',
+ alignItems: 'center',
+ justifyContent: 'center',
height: diameter,
width: diameter,
borderRadius: diameter / 2,
@@ -35,21 +37,22 @@ IdenticonComponent.prototype.render = function () {
IdenticonComponent.prototype.componentDidMount = function () {
var props = this.props
- var address = props.address
+ const { address } = props
if (!address) return
var container = findDOMNode(this)
+
var diameter = props.diameter || this.defaultDiameter
if (!isNode) {
- var img = iconFactory.iconForAddress(address, diameter, false)
+ var img = iconFactory.iconForAddress(address, diameter)
container.appendChild(img)
}
}
IdenticonComponent.prototype.componentDidUpdate = function () {
var props = this.props
- var address = props.address
+ const { address } = props
if (!address) return
@@ -62,7 +65,8 @@ IdenticonComponent.prototype.componentDidUpdate = function () {
var diameter = props.diameter || this.defaultDiameter
if (!isNode) {
- var img = iconFactory.iconForAddress(address, diameter, false)
+ var img = iconFactory.iconForAddress(address, diameter)
container.appendChild(img)
}
}
+
diff --git a/ui/app/components/loading.js b/ui/app/components/loading.js
index 88dc535df..87d6f5d20 100644
--- a/ui/app/components/loading.js
+++ b/ui/app/components/loading.js
@@ -26,18 +26,21 @@ LoadingIndicator.prototype.render = function () {
style: {
zIndex: 10,
position: 'absolute',
+ flexDirection: 'column',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
height: '100%',
width: '100%',
- background: 'rgba(255, 255, 255, 0.5)',
+ background: 'rgba(255, 255, 255, 0.8)',
},
}, [
h('img', {
src: 'images/loading.svg',
}),
+ h('br'),
+
showMessageIfAny(loadingMessage),
]) : null,
])
diff --git a/ui/app/components/tab-bar.js b/ui/app/components/tab-bar.js
index 65078e0a4..6295e7dd9 100644
--- a/ui/app/components/tab-bar.js
+++ b/ui/app/components/tab-bar.js
@@ -33,3 +33,4 @@ TabBar.prototype.render = function () {
}))
)
}
+
diff --git a/ui/app/components/token-cell.js b/ui/app/components/token-cell.js
new file mode 100644
index 000000000..d3a895d36
--- /dev/null
+++ b/ui/app/components/token-cell.js
@@ -0,0 +1,46 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const Identicon = require('./identicon')
+
+module.exports = TokenCell
+
+inherits(TokenCell, Component)
+function TokenCell () {
+ Component.call(this)
+}
+
+TokenCell.prototype.render = function () {
+ const props = this.props
+ const { address, symbol, string, network, userAddress } = props
+
+ return (
+ h('li.token-cell', {
+ style: { cursor: network === '1' ? 'pointer' : 'default' },
+ onClick: (event) => {
+ const url = urlFor(address, userAddress, network)
+ if (url) {
+ navigateTo(url)
+ }
+ },
+ }, [
+
+ h(Identicon, {
+ diameter: 50,
+ address,
+ network,
+ }),
+
+ h('h3', `${string || 0} ${symbol}`),
+ ])
+ )
+}
+
+function navigateTo (url) {
+ global.platform.openWindow({ url })
+}
+
+function urlFor (tokenAddress, address, network) {
+ return `https://etherscan.io/token/${tokenAddress}?a=${address}`
+}
+
diff --git a/ui/app/components/token-list.js b/ui/app/components/token-list.js
new file mode 100644
index 000000000..633d3ccfe
--- /dev/null
+++ b/ui/app/components/token-list.js
@@ -0,0 +1,147 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const TokenTracker = require('eth-token-tracker')
+const TokenCell = require('./token-cell.js')
+const contracts = require('eth-contract-metadata')
+
+const tokens = []
+for (const address in contracts) {
+ const contract = contracts[address]
+ if (contract.erc20) {
+ contract.address = address
+ tokens.push(contract)
+ }
+}
+
+module.exports = TokenList
+
+inherits(TokenList, Component)
+function TokenList () {
+ this.state = { tokens, isLoading: true, network: null }
+ Component.call(this)
+}
+
+TokenList.prototype.render = function () {
+ const state = this.state
+ const { tokens, isLoading, error } = state
+
+ const { userAddress } = this.props
+
+ if (isLoading) {
+ return this.message('Loading')
+ }
+
+ if (error) {
+ log.error(error)
+ return this.message('There was a problem loading your token balances.')
+ }
+
+ const network = this.props.network
+
+ const tokenViews = tokens.map((tokenData) => {
+ tokenData.network = network
+ tokenData.userAddress = userAddress
+ return h(TokenCell, tokenData)
+ })
+
+ return (
+ h('ol', {
+ style: {
+ height: '302px',
+ overflowY: 'auto',
+ },
+ }, [h('style', `
+
+ li.token-cell {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ padding: 10px;
+ }
+
+ li.token-cell > h3 {
+ margin-left: 12px;
+ }
+
+ li.token-cell:hover {
+ background: white;
+ cursor: pointer;
+ }
+
+ `)].concat(tokenViews.length ? tokenViews : this.message('No Tokens Found.')))
+ )
+}
+
+TokenList.prototype.message = function (body) {
+ return h('div', {
+ style: {
+ display: 'flex',
+ height: '250px',
+ alignItems: 'center',
+ justifyContent: 'center',
+ },
+ }, body)
+}
+
+TokenList.prototype.componentDidMount = function () {
+ this.createFreshTokenTracker()
+}
+
+TokenList.prototype.createFreshTokenTracker = function () {
+ if (this.tracker) {
+ // Clean up old trackers when refreshing:
+ this.tracker.stop()
+ this.tracker.removeListener('update', this.balanceUpdater)
+ this.tracker.removeListener('error', this.showError)
+ }
+
+ if (!global.ethereumProvider) return
+ const { userAddress } = this.props
+ this.tracker = new TokenTracker({
+ userAddress,
+ provider: global.ethereumProvider,
+ tokens: tokens,
+ pollingInterval: 8000,
+ })
+
+
+ // Set up listener instances for cleaning up
+ this.balanceUpdater = this.updateBalances.bind(this)
+ this.showError = (error) => {
+ this.setState({ error, isLoading: false })
+ }
+ this.tracker.on('update', this.balanceUpdater)
+ this.tracker.on('error', this.showError)
+
+ this.tracker.updateBalances()
+ .then(() => {
+ this.updateBalances(this.tracker.serialize())
+ })
+ .catch((reason) => {
+ log.error(`Problem updating balances`, reason)
+ this.setState({ isLoading: false })
+ })
+}
+
+TokenList.prototype.componentWillUpdate = function (nextProps) {
+ if (nextProps.network === 'loading') return
+ const oldNet = this.props.network
+ const newNet = nextProps.network
+
+ if (oldNet && newNet && newNet !== oldNet) {
+ this.setState({ isLoading: true })
+ this.createFreshTokenTracker()
+ }
+}
+
+TokenList.prototype.updateBalances = function (tokenData) {
+ const heldTokens = tokenData.filter(token => token.balance !== '0' && token.string !== '0.000')
+ this.setState({ tokens: heldTokens, isLoading: false })
+}
+
+TokenList.prototype.componentWillUnmount = function () {
+ if (!this.tracker) return
+ this.tracker.stop()
+}
+
diff --git a/ui/app/components/transaction-list.js b/ui/app/components/transaction-list.js
index 37a757309..3b4ba741e 100644
--- a/ui/app/components/transaction-list.js
+++ b/ui/app/components/transaction-list.js
@@ -36,17 +36,6 @@ TransactionList.prototype.render = function () {
}
`),
- h('h3.flex-center.text-transform-uppercase', {
- style: {
- background: '#EBEBEB',
- color: '#AEAEAE',
- paddingTop: '4px',
- paddingBottom: '4px',
- },
- }, [
- 'History',
- ]),
-
h('.tx-list', {
style: {
overflowY: 'auto',