aboutsummaryrefslogtreecommitdiffstats
path: root/ui/app/components/token-list.js
diff options
context:
space:
mode:
Diffstat (limited to 'ui/app/components/token-list.js')
-rw-r--r--ui/app/components/token-list.js147
1 files changed, 147 insertions, 0 deletions
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()
+}
+