implement adding custom token

This commit is contained in:
Mikhail Mikheev 2019-04-22 17:45:05 +04:00
parent 7dc2f235f8
commit 5b109dd60a
4 changed files with 108 additions and 78 deletions

View File

@ -1,7 +1,7 @@
// @flow // @flow
import { Map } from 'immutable' import { Map } from 'immutable'
import { handleActions, type ActionType } from 'redux-actions' import { handleActions, type ActionType } from 'redux-actions'
import { type Token } from '~/logic/tokens/store/model/token' import { type Token, makeToken } from '~/logic/tokens/store/model/token'
import { ADD_TOKEN } from '~/logic/tokens/store/actions/addToken' import { ADD_TOKEN } from '~/logic/tokens/store/actions/addToken'
import { REMOVE_TOKEN } from '~/logic/tokens/store/actions/removeToken' import { REMOVE_TOKEN } from '~/logic/tokens/store/actions/removeToken'
import { ADD_TOKENS } from '~/logic/tokens/store/actions/saveTokens' import { ADD_TOKENS } from '~/logic/tokens/store/actions/saveTokens'
@ -27,7 +27,7 @@ export default handleActions<State, *>(
const { token } = action.payload const { token } = action.payload
const { address: tokenAddress } = token const { address: tokenAddress } = token
return state.set(tokenAddress, token) return state.set(tokenAddress, makeToken(token))
}, },
[REMOVE_TOKEN]: (state: State, action: ActionType<Function>): State => { [REMOVE_TOKEN]: (state: State, action: ActionType<Function>): State => {
const { token } = action.payload const { token } = action.payload

View File

@ -1,13 +1,16 @@
// @flow // @flow
import fetchTokens from '~/logic/tokens/store/actions/fetchTokens' import fetchTokens from '~/logic/tokens/store/actions/fetchTokens'
import { addToken } from '~/logic/tokens/store/actions/addToken'
import updateActiveTokens from '~/routes/safe/store/actions/updateActiveTokens' import updateActiveTokens from '~/routes/safe/store/actions/updateActiveTokens'
export type Actions = { export type Actions = {
fetchTokens: Function, fetchTokens: Function,
updateActiveTokens: Function, updateActiveTokens: Function,
addToken: Function,
} }
export default { export default {
fetchTokens, fetchTokens,
addToken,
updateActiveTokens, updateActiveTokens,
} }

View File

@ -35,6 +35,23 @@ class Tokens extends React.Component<Props, State> {
activeScreen, activeScreen,
}) })
onTokenAdd = (formValues) => {
const {
addToken, updateActiveTokens, safeAddress, activeTokens,
} = this.props
const activeTokensAddresses = List(activeTokens.map(({ address }) => address))
const token = {
address: formValues.tokenAddress,
decimals: formValues.tokenDecimals,
symbol: formValues.tokenSymbol,
name: formValues.tokenSymbol,
}
addToken(token)
updateActiveTokens(safeAddress, activeTokensAddresses.push(token.address))
}
render() { render() {
const { const {
onClose, classes, tokens, activeTokens, fetchTokens, updateActiveTokens, safeAddress, onClose, classes, tokens, activeTokens, fetchTokens, updateActiveTokens, safeAddress,
@ -62,7 +79,9 @@ class Tokens extends React.Component<Props, State> {
setActiveScreen={this.setActiveScreen} setActiveScreen={this.setActiveScreen}
/> />
)} )}
{activeScreen === 'addCustomToken' && <AddCustomToken setActiveScreen={this.setActiveScreen} />} {activeScreen === 'addCustomToken' && (
<AddCustomToken setActiveScreen={this.setActiveScreen} onTokenAdd={this.onTokenAdd} onClose={onClose} />
)}
</React.Fragment> </React.Fragment>
) )
} }

View File

@ -1,5 +1,5 @@
// @flow // @flow
import React, { Component } from 'react' import React from 'react'
import { withStyles } from '@material-ui/core/styles' import { withStyles } from '@material-ui/core/styles'
import Block from '~/components/layout/Block' import Block from '~/components/layout/Block'
import Paragraph from '~/components/layout/Paragraph' import Paragraph from '~/components/layout/Paragraph'
@ -18,83 +18,91 @@ import {
import TokenPlaceholder from '~/routes/safe/components/Balances/assets/token_placeholder.svg' import TokenPlaceholder from '~/routes/safe/components/Balances/assets/token_placeholder.svg'
import { styles } from './style' import { styles } from './style'
class AddCustomToken extends Component { type Props = {
handleSubmit = (values) => { classes: Object,
console.log(values) onTokenAdd: Function,
setActiveScreen: Function,
onClose: Function,
}
const AddCustomToken = (props: Props) => {
const {
classes, setActiveScreen, onTokenAdd, onClose,
} = props
const goBackToTokenList = () => {
setActiveScreen('tokenList')
}
const handleSubmit = (values) => {
onTokenAdd(values)
onClose()
} }
render() { return (
const { classes, setActiveScreen } = this.props <React.Fragment>
const goBackToTokenList = () => { <GnoForm onSubmit={handleSubmit}>
setActiveScreen('tokenList') {() => (
} <React.Fragment>
<Block className={classes.formContainer}>
return ( <Paragraph noMargin className={classes.title} weight="bolder" size="lg">
<React.Fragment> Add custom token
<GnoForm onSubmit={this.handleSubmit}> </Paragraph>
{(submitting: boolean, validating: boolean, ...rest: any) => ( <Field
<React.Fragment> name="tokenAddress"
<Block className={classes.formContainer}> component={TextField}
<Paragraph noMargin className={classes.title} weight="bolder" size="lg"> type="text"
Add custom token validate={composeValidators(required, mustBeEthereumAddress)}
</Paragraph> placeholder="Token contract address*"
<Field text="Token contract address*"
name="tokenAddress" className={classes.addressInput}
component={TextField} />
type="text" <Row>
validate={composeValidators(required, mustBeEthereumAddress)} <Col xs={6} layout="column">
placeholder="Token contract address*" <Field
text="Token contract address*" name="tokenSymbol"
className={classes.addressInput} component={TextField}
/> type="text"
<Row> validate={required}
<Col xs={6} layout="column"> placeholder="Token symbol*"
<Field text="Token symbol"
name="tokenSymbol" className={classes.addressInput}
component={TextField} />
type="text" <Field
validate={required} name="tokenDecimals"
placeholder="Token symbol*" component={TextField}
text="Token symbol" type="text"
className={classes.addressInput} validate={composeValidators(required, mustBeInteger)}
/> placeholder="Token decimals*"
<Field text="Token decimals*"
name="tokenDecimals" className={classes.addressInput}
component={TextField} />
type="text" <Block align="left">
validate={composeValidators(required, mustBeInteger)} <Field name="showForAllSafes" component={Checkbox} type="checkbox" className={classes.checkbox} />
placeholder="Token decimals*" <Paragraph weight="bolder" size="md" className={classes.checkboxLabel}>
text="Token decimals*" Display token for all safes
className={classes.addressInput} </Paragraph>
/> </Block>
<Block align="left"> </Col>
<Field name="showForAllSafes" component={Checkbox} type="checkbox" className={classes.checkbox} /> <Col xs={6} layout="column" align="center">
<Paragraph weight="bolder" size="md" className={classes.checkboxLabel}> <Paragraph className={classes.tokenImageHeading}>Token Image</Paragraph>
Display token for all safes <Img src={TokenPlaceholder} alt="Token image" height={100} />
</Paragraph> </Col>
</Block>
</Col>
<Col xs={6} layout="column" align="center">
<Paragraph className={classes.tokenImageHeading}>Token Image</Paragraph>
<Img src={TokenPlaceholder} alt="Token image" height={100} />
</Col>
</Row>
</Block>
<Hairline />
<Row align="center" className={classes.buttonRow}>
<Button className={classes.button} minWidth={140} onClick={goBackToTokenList}>
Cancel
</Button>
<Button type="submit" className={classes.button} variant="contained" minWidth={140} color="primary">
Save
</Button>
</Row> </Row>
</React.Fragment> </Block>
)} <Hairline />
</GnoForm> <Row align="center" className={classes.buttonRow}>
</React.Fragment> <Button className={classes.button} minWidth={140} onClick={goBackToTokenList}>
) Cancel
} </Button>
<Button type="submit" className={classes.button} variant="contained" minWidth={140} color="primary">
Save
</Button>
</Row>
</React.Fragment>
)}
</GnoForm>
</React.Fragment>
)
} }
const AddCustomTokenComponent = withStyles(styles)(AddCustomToken) const AddCustomTokenComponent = withStyles(styles)(AddCustomToken)