toolyip for long token names, full mode view styles fix, search is available only for Mainnet

This commit is contained in:
Victor Baranov 2018-09-17 14:49:44 +03:00
parent ff77b0023f
commit 053f3447ab
8 changed files with 206 additions and 189 deletions

View File

@ -58,6 +58,7 @@ class AddTokenScreen extends Component {
identities: PropTypes.object,
address: PropTypes.string,
dispatch: PropTypes.func,
network: PropTypes.string,
}
constructor (props) {
@ -111,6 +112,19 @@ class AddTokenScreen extends Component {
}
render () {
const { network } = this.props
const networkID = parseInt(network)
let views = []
networkID === 1 ? views = [h(TabBar, {
tabs: [
{ content: 'Search', key: SEARCH_TAB },
{ content: 'Custom', key: CUSTOM_TOKEN_TAB },
],
defaultTab: this.state.displayedTab || CUSTOM_TOKEN_TAB,
tabSelected: (key) => this.setCurrentAddTokenTab(key),
}),
this.tabSwitchView()] : views = [this.renderAddToken()]
return (
h('.flex-column.flex-grow', {
style: {
@ -130,16 +144,7 @@ class AddTokenScreen extends Component {
}, 'Add Token'),
]),
h(TabBar, {
tabs: [
{ content: 'Search', key: SEARCH_TAB },
{ content: 'Custom', key: CUSTOM_TOKEN_TAB },
],
defaultTab: this.state.displayedTab || CUSTOM_TOKEN_TAB,
tabSelected: (key) => this.setCurrentAddTokenTab(key),
}),
this.tabSwitchView(),
...views,
])
)
}
@ -149,160 +154,172 @@ class AddTokenScreen extends Component {
}
tabSwitchView () {
const props = this.props
const state = this.state
const { warning, customSymbol, customDecimals, tokenSelectorError, selectedTokens, searchResults, displayedTab } = state
const { network, clearPendingTokens, goHome, addToken } = props
const { displayedTab } = state
switch (displayedTab) {
case CUSTOM_TOKEN_TAB:
return h('.flex-column.flex-justify-center.flex-grow.select-none', [
warning ? h('div', {
style: {
margin: '20px 30px 0 30px',
},
}, [
h('.error', {
style: {
display: 'block',
},
}, warning),
]) : null,
h('.flex-space-around', {
style: {
padding: '30px',
},
}, [
h('div', [
h(Tooltip, {
position: 'top',
title: 'The contract of the actual token contract.',
}, [
h('span', {
style: { fontWeight: 'bold'},
}, 'Token Address' /* this.context.t('tokenAddress')*/),
]),
]),
h('section.flex-row.flex-center', [
h('input.large-input#token-address', {
name: 'address',
placeholder: 'Token Contract Address',
style: {
width: '100%',
margin: '10px 0',
},
onChange: e => this.handleCustomAddressChange(e.target.value),
}),
]),
h('div', [
h('span', {
style: { fontWeight: 'bold', paddingRight: '10px'},
}, 'Token Symbol' /* this.context.t('tokenSymbol')*/),
]),
h('div', { style: {display: 'flex'} }, [
h('input.large-input#token_symbol', {
placeholder: `Like "ETH"`,
value: customSymbol,
style: {
width: '100%',
margin: '10px 0',
},
onChange: e => this.handleCustomSymbolChange(e.target.value),
}),
]),
h('div', [
h('span', {
style: { fontWeight: 'bold', paddingRight: '10px'},
}, 'Decimals of Precision' /* this.context.t('decimal')*/),
]),
h('div', { style: {display: 'flex'} }, [
h('input.large-input#token_decimals', {
value: customDecimals,
type: 'number',
min: 0,
max: 36,
style: {
width: '100%',
margin: '10px 0',
},
onChange: e => this.handleCustomDecimalsChange(e.target.value),
}),
]),
h('div', {
key: 'buttons',
style: {
alignSelf: 'center',
float: 'right',
marginTop: '10px',
},
}, [
h('button.btn-violet', {
onClick: () => {
goHome()
},
}, 'Cancel' /* this.context.t('cancel')*/),
h('button', {
onClick: (event) => {
const valid = this.validateInputs()
if (!valid) return
const { customAddress, customSymbol, customDecimals } = this.state
addToken(customAddress.trim(), customSymbol.trim(), customDecimals, network)
.then(() => {
// this.props.dispatch(actions.goHome())
goHome()
})
},
}, 'Add' /* this.context.t('addToken')*/),
]),
]),
])
return this.renderAddToken()
default:
return h('div', [
h('.add-token__search-token', [
h(TokenSearch, {
onSearch: ({ results = [] }) => this.setState({ searchResults: results }),
error: tokenSelectorError,
}),
h('.add-token__token-list', {
style: {
marginTop: '20px',
height: '250px',
overflow: 'auto',
},
}, [
h(TokenList, {
results: searchResults,
selectedTokens: selectedTokens,
onToggleToken: token => this.handleToggleToken(token),
}),
]),
]),
h('.page-container__footer', [
h('.page-container__footer-container', [
h('button.btn-violet', {
onClick: () => {
clearPendingTokens()
goHome()
},
}, 'Cancel' /* this.context.t('cancel')*/),
h('button', {
onClick: () => this.handleNext(),
disabled: this.hasError() || !this.hasSelected(),
}, 'Next' /* this.context.t('next')*/),
]),
]),
])
return this.renderTabBar()
}
}
renderAddToken () {
const props = this.props
const state = this.state
const { warning, customSymbol, customDecimals } = state
const { network, goHome, addToken } = props
return h('.flex-column.flex-justify-center.flex-grow.select-none', [
warning ? h('div', {
style: {
margin: '20px 30px 0 30px',
},
}, [
h('.error', {
style: {
display: 'block',
},
}, warning),
]) : null,
h('.flex-space-around', {
style: {
padding: '30px',
},
}, [
h('div', [
h(Tooltip, {
position: 'top',
title: 'The contract of the actual token contract.',
}, [
h('span', {
style: { fontWeight: 'bold'},
}, 'Token Address' /* this.context.t('tokenAddress')*/),
]),
]),
h('section.flex-row.flex-center', [
h('input.large-input#token-address', {
name: 'address',
placeholder: 'Token Contract Address',
style: {
width: '100%',
margin: '10px 0',
},
onChange: e => this.handleCustomAddressChange(e.target.value),
}),
]),
h('div', [
h('span', {
style: { fontWeight: 'bold', paddingRight: '10px'},
}, 'Token Symbol' /* this.context.t('tokenSymbol')*/),
]),
h('div', { style: {display: 'flex'} }, [
h('input.large-input#token_symbol', {
placeholder: `Like "ETH"`,
value: customSymbol,
style: {
width: '100%',
margin: '10px 0',
},
onChange: e => this.handleCustomSymbolChange(e.target.value),
}),
]),
h('div', [
h('span', {
style: { fontWeight: 'bold', paddingRight: '10px'},
}, 'Decimals of Precision' /* this.context.t('decimal')*/),
]),
h('div', { style: {display: 'flex'} }, [
h('input.large-input#token_decimals', {
value: customDecimals,
type: 'number',
min: 0,
max: 36,
style: {
width: '100%',
margin: '10px 0',
},
onChange: e => this.handleCustomDecimalsChange(e.target.value),
}),
]),
h('div', {
key: 'buttons',
style: {
alignSelf: 'center',
float: 'right',
marginTop: '10px',
},
}, [
h('button.btn-violet', {
onClick: () => {
goHome()
},
}, 'Cancel' /* this.context.t('cancel')*/),
h('button', {
onClick: (event) => {
const valid = this.validateInputs()
if (!valid) return
const { customAddress, customSymbol, customDecimals } = this.state
addToken(customAddress.trim(), customSymbol.trim(), customDecimals, network)
.then(() => {
goHome()
})
},
}, 'Add' /* this.context.t('addToken')*/),
]),
]),
])
}
renderTabBar () {
const props = this.props
const state = this.state
const { tokenSelectorError, selectedTokens, searchResults } = state
const { clearPendingTokens, goHome } = props
return h('div', [
h('.add-token__search-token', [
h(TokenSearch, {
onSearch: ({ results = [] }) => this.setState({ searchResults: results }),
error: tokenSelectorError,
}),
h('.add-token__token-list', {
style: {
marginTop: '20px',
height: '250px',
overflow: 'auto',
},
}, [
h(TokenList, {
results: searchResults,
selectedTokens: selectedTokens,
onToggleToken: token => this.handleToggleToken(token),
}),
]),
]),
h('.page-container__footer', [
h('.page-container__footer-container', [
h('button.btn-violet', {
onClick: () => {
clearPendingTokens()
goHome()
},
}, 'Cancel' /* this.context.t('cancel')*/),
h('button', {
onClick: () => this.handleNext(),
disabled: this.hasError() || !this.hasSelected(),
}, 'Next' /* this.context.t('next')*/),
]),
]),
])
}
componentWillMount () {
if (typeof global.ethereumProvider === 'undefined') return
@ -316,15 +333,6 @@ class AddTokenScreen extends Component {
displayWarning('')
}
// tokenAddressDidChange (event) {
// const el = event.target
// const address = el.value.trim()
// if (ethUtil.isValidAddress(address) && address !== emptyAddr) {
// this.setState({ address })
// this.attemptToAutoFillTokenParams(address)
// }
// }
validateInputs () {
let msg = ''
const state = this.state

View File

@ -1,5 +1,5 @@
.page-container {
width: 408px;
width: 100%;
background-color: #fff;
box-shadow: 0 0 7px 0 rgba(0, 0, 0, 0.08);
z-index: 25;

View File

@ -1530,7 +1530,6 @@ function showAccountDetail (address) {
}
function backToAccountDetail (address) {
console.log('### backToAccountDetail ###')
return {
type: actions.BACK_TO_ACCOUNT_DETAIL,
value: address,

View File

@ -3,6 +3,8 @@ import PropTypes from 'prop-types'
import classnames from 'classnames'
import { checkExistingAddresses } from '../util'
import TokenListPlaceholder from './token-list-placeholder'
import h from 'react-hyperscript'
import Tooltip from '../../../../../../old-ui/app/components/tooltip.js'
export default class InfoBox extends Component {
static contextTypes = {
@ -24,7 +26,7 @@ export default class InfoBox extends Component {
: (
<div className="token-list">
<div className="token-list__title">
{ this.context.t('searchResults') }
{ 'searchResults' /* this.context.t('searchResults')*/ }
</div>
<div className="token-list__tokens-container">
{
@ -32,24 +34,34 @@ export default class InfoBox extends Component {
.map((_, i) => {
const { logo, symbol, name, address } = results[i] || {}
const tokenAlreadyAdded = checkExistingAddresses(address, tokens)
const title = `${name} (${symbol})`
const isLongTitle = title.length > 28
const tokenRow = (key) => h(`.${classnames('token-list__token', {
'token-list__token--selected': selectedTokens[address],
'token-list__token--disabled': tokenAlreadyAdded,
}).split(' ').join('.')}`, {
onClick: () => !tokenAlreadyAdded && onToggleToken(results[i]),
key: key ? key : 'tokenRow'
}, [
h('.token-list__token-icon', {
style: {
backgroundImage: logo && `url(images/contract/${logo})`,
},
}),
h('.token-list__token-data', [
h('span.token-list__token-name', title),
]),
])
return Boolean(logo || symbol || name) && (
<div
className={classnames('token-list__token', {
'token-list__token--selected': selectedTokens[address],
'token-list__token--disabled': tokenAlreadyAdded,
})}
onClick={() => !tokenAlreadyAdded && onToggleToken(results[i])}
key={i}
>
<div
className="token-list__token-icon"
style={{ backgroundImage: logo && `url(images/contract/${logo})` }}>
</div>
<div className="token-list__token-data">
<span className="token-list__token-name">{ `${name} (${symbol})` }</span>
</div>
</div>
isLongTitle ? h(Tooltip, {
position: 'top',
title: title,
key: i,
}, [
tokenRow()
]) : tokenRow(i)
)
})
}

View File

@ -35,6 +35,7 @@ export default class ConfirmAddToken extends Component {
render () {
const { /* history,*/ addTokens, clearPendingTokens, pendingTokens, goHome } = this.props
const areMultipleTokens = pendingTokens && Object.keys(pendingTokens).length > 1
return (
<div className="page-container">
@ -43,7 +44,7 @@ export default class ConfirmAddToken extends Component {
{ 'Add Tokens' /* this.context.t('addTokens')*/ }
</h2>
<p className="confirm-label">
{ 'Would you like to add these tokens?' /* this.context.t('likeToAddTokens')*/ }
{ areMultipleTokens ? 'Would you like to add these tokens?' : 'Would you like to add this token?' /* this.context.t('likeToAddTokens')*/ }
</p>
</div>
<div className="page-container__content">

View File

@ -106,7 +106,6 @@ WalletView.prototype.render = function () {
identities,
} = this.props
// temporary logs + fake extra wallets
// console.log('walletview, selectedAccount:', selectedAccount)
const checksummedAddress = checksumAddress(selectedAddress)

View File

@ -397,7 +397,6 @@ function reduceApp (state, action) {
})
case actions.BACK_TO_ACCOUNT_DETAIL:
console.log('BACK_TO_ACCOUNT_DETAIL')
return extend(appState, {
currentView: {
name: 'accountDetail',

View File

@ -108,7 +108,6 @@ function transactionsSelector (state) {
const transactions = state.metamask.selectedAddressTxList || []
const txsToRender = !shapeShiftTxList ? transactions.concat(unapprovedMsgs) : transactions.concat(unapprovedMsgs, shapeShiftTxList)
// console.log({txsToRender, selectedTokenAddress})
return selectedTokenAddress
? txsToRender
.filter(({ txParams }) => txParams && txParams.to === selectedTokenAddress)