diff options
author | Dan Finlay <dan@danfinlay.com> | 2017-06-14 08:47:56 +0800 |
---|---|---|
committer | Dan Finlay <dan@danfinlay.com> | 2017-06-14 08:53:42 +0800 |
commit | 108c4ab2c58074aa8148828fbbef8cbf3a4e23f5 (patch) | |
tree | e09b0ee929a73cd5d545ac90f695b23568c9ef58 /ui | |
parent | de500250c463f51f68abff44c8ed6c20912b48c0 (diff) | |
download | tangerine-wallet-browser-108c4ab2c58074aa8148828fbbef8cbf3a4e23f5.tar tangerine-wallet-browser-108c4ab2c58074aa8148828fbbef8cbf3a4e23f5.tar.gz tangerine-wallet-browser-108c4ab2c58074aa8148828fbbef8cbf3a4e23f5.tar.bz2 tangerine-wallet-browser-108c4ab2c58074aa8148828fbbef8cbf3a4e23f5.tar.lz tangerine-wallet-browser-108c4ab2c58074aa8148828fbbef8cbf3a4e23f5.tar.xz tangerine-wallet-browser-108c4ab2c58074aa8148828fbbef8cbf3a4e23f5.tar.zst tangerine-wallet-browser-108c4ab2c58074aa8148828fbbef8cbf3a4e23f5.zip |
Auto populate token list with popular token balances
Half implements #175
Things to do:
- Add ability to add tokens to the list.
- Persist the token tab selection (so it is an implicit preference)
- Check what's up with the token-tracker polling, it seems like it is not waiting the interval.
Diffstat (limited to 'ui')
-rw-r--r-- | ui/app/account-detail.js | 17 | ||||
-rw-r--r-- | ui/app/components/identicon.js | 6 | ||||
-rw-r--r-- | ui/app/components/tab-bar.js | 1 | ||||
-rw-r--r-- | ui/app/components/token-cell.js | 22 | ||||
-rw-r--r-- | ui/app/components/token-list.js | 49 | ||||
-rw-r--r-- | ui/app/info.js | 1 | ||||
-rw-r--r-- | ui/lib/icon-factory.js | 4 |
7 files changed, 68 insertions, 32 deletions
diff --git a/ui/app/account-detail.js b/ui/app/account-detail.js index 5b2588ec5..8234a8438 100644 --- a/ui/app/account-detail.js +++ b/ui/app/account-detail.js @@ -39,7 +39,7 @@ function mapStateToProps (state) { inherits(AccountDetailScreen, Component) function AccountDetailScreen () { - this.state = {} + this.state = { tabSelection: 'history' } Component.call(this) } @@ -251,13 +251,7 @@ AccountDetailScreen.prototype.subview = function () { } AccountDetailScreen.prototype.tabSections = function () { - var subview - try { - subview = this.props.accountDetail.subview - } catch (e) { - subview = null - } - + const tabSelection = this.state.tabSelection return h('section.tabSection', [ h(TabBar, { @@ -265,7 +259,7 @@ AccountDetailScreen.prototype.tabSections = function () { { content: 'History', key: 'history' }, { content: 'Tokens', key: 'tokens' }, ], - defaultTab: subview || 'history', + defaultTab: tabSelection || 'history', tabSelected: (key) => { this.setState({ tabSelection: key }) }, @@ -276,12 +270,13 @@ AccountDetailScreen.prototype.tabSections = function () { } AccountDetailScreen.prototype.tabSwitchView = function () { - const userAddress = this.props.address + const props = this.props + const { address, network } = props const tabSelection = this.state.tabSelection || 'history' switch (tabSelection) { case 'tokens': - return h(TokenList, { userAddress }) + return h(TokenList, { userAddress: address, network }) default: return this.transactionList() } diff --git a/ui/app/components/identicon.js b/ui/app/components/identicon.js index 58bd2bdc4..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, @@ -40,8 +42,8 @@ IdenticonComponent.prototype.componentDidMount = function () { if (!address) return var container = findDOMNode(this) - var diameter = props.diameter || this.defaultDiameter + var diameter = props.diameter || this.defaultDiameter if (!isNode) { var img = iconFactory.iconForAddress(address, diameter) container.appendChild(img) 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 index 879dc01d1..ad7f55345 100644 --- a/ui/app/components/token-cell.js +++ b/ui/app/components/token-cell.js @@ -12,11 +12,19 @@ function TokenCell () { TokenCell.prototype.render = function () { const props = this.props - const { address, symbol, string, network } = props - log.info({ address, symbol, string }) + const { address, symbol, string, network, userAddress } = props + log.info({ address, symbol, string, network }) return ( - h('li.token-cell', [ + 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, @@ -29,3 +37,11 @@ TokenCell.prototype.render = function () { ) } +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 index 6589dea62..b79fbccf3 100644 --- a/ui/app/components/token-list.js +++ b/ui/app/components/token-list.js @@ -3,35 +3,49 @@ 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 Loading = require('./loading') + +const tokens = [] +for (let address in contracts) { + const contract = contracts[address] + if (contract.erc20) { + contract.address = address + tokens.push(contract) + } +} module.exports = TokenList inherits(TokenList, Component) function TokenList () { - - // Hard coded for development for now: - const tokens = [ - { address: '0x48c80F1f4D53D5951e5D5438B54Cba84f29F32a5', symbol: 'REP', balance: 'aa'}, - { address: '0xc66ea802717bfb9833400264dd12c2bceaa34a6d', symbol: 'MKR', balance: '1000', decimals: 18}, - { address: '0xa74476443119A942dE498590Fe1f2454d7D4aC0d', symbol: 'GOL', balance: 'ff'}, - { address: '0xaec2e87e0a235266d9c5adc9deb4b2e29b54d009', symbol: 'SNGLS', balance: '0' }, - ] - - this.state = { tokens } + this.state = { tokens, isLoading: true } Component.call(this) } TokenList.prototype.render = function () { - const tokens = this.state.tokens + const state = this.state + const { tokens, isLoading } = state + + const { userAddress } = this.props + + if (isLoading) return h(Loading, { isLoading }) + const network = this.props.network const tokenViews = tokens.map((tokenData) => { tokenData.network = network + tokenData.userAddress = userAddress return h(TokenCell, tokenData) }) return ( - h('ol', [h('style', ` + h('ol', { + style: { + height: '302px', + overflowY: 'auto', + }, + }, [h('style', ` li.token-cell { display: flex; @@ -54,19 +68,26 @@ TokenList.prototype.render = function () { } TokenList.prototype.componentDidMount = function () { + if (!global.ethereumProvider) return const { userAddress } = this.props this.tracker = new TokenTracker({ userAddress, - provider: web3.currentProvider, + provider: global.ethereumProvider, tokens: this.state.tokens, + pollingInterval: 8000, }) this.setState({ tokens: this.tracker.serialize() }) - this.tracker.on('update', (tokenData) => this.setState({ tokens: tokenData })) + this.tracker.on('update', (tokenData) => { + const heldTokens = tokenData.filter(token => token.balance !== '0' && token.string !== '0.000') + this.setState({ tokens: heldTokens, isLoading: false }) + }) this.tracker.updateBalances() } TokenList.prototype.componentWillUnmount = function () { + if (!this.tracker) return this.tracker.stop() } + diff --git a/ui/app/info.js b/ui/app/info.js index aa4503b62..825796ed6 100644 --- a/ui/app/info.js +++ b/ui/app/info.js @@ -155,3 +155,4 @@ InfoScreen.prototype.render = function () { InfoScreen.prototype.navigateTo = function (url) { global.platform.openWindow({ url }) } + diff --git a/ui/lib/icon-factory.js b/ui/lib/icon-factory.js index 4ee6b600b..27a74de66 100644 --- a/ui/lib/icon-factory.js +++ b/ui/lib/icon-factory.js @@ -44,7 +44,7 @@ IconFactory.prototype.generateNewIdenticon = function (address, diameter) { // util function iconExistsFor (address) { - return (contractMap.address) && isValidAddress(address) && (contractMap[address].logo) + return contractMap[address] && isValidAddress(address) && contractMap[address].logo } function imageElFor (address) { @@ -53,7 +53,7 @@ function imageElFor (address) { const path = `images/contract/${fileName}` const img = document.createElement('img') img.src = path - img.style.width = '100%' + img.style.width = '75%' return img } |