nifty-wallet/old-ui/app/components/token-list.js

221 lines
5.6 KiB
JavaScript
Raw Normal View History

2017-11-14 08:04:23 -08:00
const Component = require('react').Component
const h = require('react-hyperscript')
const inherits = require('util').inherits
2018-08-22 05:32:45 -07:00
const TokenTracker = require('eth-token-watcher')
2017-11-14 08:04:23 -08:00
const TokenCell = require('./token-cell.js')
const log = require('loglevel')
2017-11-14 08:04:23 -08:00
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, network } = this.props
if (isLoading) {
return this.message('Loading')
}
if (error) {
log.error(error)
return h('.hotFix', {
style: {
padding: '30px',
2017-11-14 08:04:23 -08:00
},
}, [
'We had trouble loading your token balances. You can view them ',
h('span.hotFix', {
style: {
2018-08-20 09:45:52 -07:00
color: '#60db97',
2017-11-14 08:04:23 -08:00
cursor: 'pointer',
},
onClick: () => {
global.platform.openWindow({
url: `https://ethplorer.io/address/${userAddress}`,
})
},
}, 'here'),
])
}
2018-08-22 05:32:45 -07:00
const tokensFromCurrentNetwork = tokens.filter(token => (parseInt(token.network) === parseInt(network) || !token.network))
const tokenViews = tokensFromCurrentNetwork.map((tokenData, ind) => {
2017-11-14 08:04:23 -08:00
tokenData.userAddress = userAddress
2018-09-20 07:36:44 -07:00
const isPenultimateTokenCell = ind === (tokensFromCurrentNetwork.length - 2)
const isLastTokenCell = ind === (tokensFromCurrentNetwork.length - 1)
const multipleTokens = tokensFromCurrentNetwork.length > 1
const more2Tokens = tokensFromCurrentNetwork.length > 2
const last2Tokens = more2Tokens && (isLastTokenCell || isPenultimateTokenCell)
const last1Token = !more2Tokens && isLastTokenCell
const menuToTop = multipleTokens && (last1Token || last2Tokens)
2018-07-24 04:59:24 -07:00
return h(TokenCell, {
...tokenData,
2018-07-26 13:45:52 -07:00
isLastTokenCell,
2018-09-20 07:36:44 -07:00
menuToTop,
2018-07-24 04:59:24 -07:00
removeToken: this.props.removeToken,
})
2017-11-14 08:04:23 -08:00
})
return h('.full-flex-height', [
this.renderTokenStatusBar(),
h('ol.full-flex-height.flex-column', {
style: {
overflowY: 'auto',
display: 'flex',
flexDirection: 'column',
},
}, [
h('style', `
li.token-cell {
display: flex;
flex-direction: row;
align-items: center;
padding: 10px;
min-height: 50px;
}
li.token-cell > h3 {
margin-left: 12px;
}
li.token-cell:hover {
background: white;
cursor: pointer;
}
`),
...tokenViews,
h('.flex-grow'),
]),
])
}
TokenList.prototype.renderTokenStatusBar = function () {
const { tokens } = this.state
2018-08-22 05:32:45 -07:00
const { network } = this.props
const tokensFromCurrentNetwork = tokens.filter(token => (parseInt(token.network) === parseInt(network) || !token.network))
2017-11-14 08:04:23 -08:00
let msg
2018-08-22 05:32:45 -07:00
if (tokensFromCurrentNetwork.length === 1) {
2017-11-14 08:04:23 -08:00
msg = `You own 1 token`
2018-08-22 05:32:45 -07:00
} else if (tokensFromCurrentNetwork.length > 1) {
msg = `You own ${tokensFromCurrentNetwork.length} tokens`
2017-11-14 08:04:23 -08:00
} else {
msg = `No tokens found`
}
return h('div', {
style: {
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
minHeight: '70px',
padding: '30px 30px 10px',
2017-11-14 08:04:23 -08:00
},
}, [
h('span', msg),
h('button', {
key: 'reveal-account-bar',
onClick: (event) => {
event.preventDefault()
this.props.addToken()
},
style: {
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
},
}, [
2018-07-26 04:42:04 -07:00
'Add Token',
2017-11-14 08:04:23 -08:00
]),
])
}
TokenList.prototype.message = function (body) {
return h('div', {
style: {
display: 'flex',
height: '250px',
alignItems: 'center',
justifyContent: 'center',
padding: '30px',
},
}, body)
}
TokenList.prototype.componentDidMount = function () {
this.createFreshTokenTracker()
}
TokenList.prototype.createFreshTokenTracker = function (userAddress) {
2017-11-14 08:04:23 -08:00
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
this.tracker = new TokenTracker({
userAddress: userAddress || this.props.userAddress,
2017-11-14 08:04:23 -08:00
provider: global.ethereumProvider,
tokens: this.props.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
const oldAddress = this.props.userAddress
const newAddress = nextProps.userAddress
if (oldNet && newNet && (newNet !== oldNet || newAddress !== oldAddress)) {
2017-11-14 08:04:23 -08:00
this.setState({ isLoading: true })
this.createFreshTokenTracker(newAddress)
2017-11-14 08:04:23 -08:00
}
}
TokenList.prototype.updateBalances = function (tokens) {
2018-09-11 04:11:28 -07:00
this.setState({ tokens, error: null, isLoading: false })
2017-11-14 08:04:23 -08:00
}
TokenList.prototype.componentWillUnmount = function () {
if (!this.tracker) return
this.tracker.stop()
}