implement adding custom token
This commit is contained in:
parent
7dc2f235f8
commit
5b109dd60a
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue