add qr scanner to send funds/send custom tx flows

This commit is contained in:
Mikhail Mikheev 2019-10-04 16:16:53 +04:00
parent c38325bca5
commit a113f2321d
8 changed files with 98 additions and 24 deletions

View File

@ -28,7 +28,7 @@ import { getAccountsFrom } from '~/routes/open/utils/safeDataExtractor'
import Hairline from '~/components/layout/Hairline'
import trash from '~/assets/icons/trash.svg'
import QRIcon from '~/assets/icons/qrcode.svg'
import ScanQRModal from './ScanQRModal'
import ScanQRModal from '~/components/ScanQRModal'
import { getAddressValidator } from './validators'
import { styles } from './style'

View File

@ -1,5 +1,5 @@
// @flow
import React from 'react'
import React, { useState } from 'react'
import { withStyles } from '@material-ui/core/styles'
import Close from '@material-ui/icons/Close'
import InputAdornment from '@material-ui/core/InputAdornment'
@ -10,19 +10,19 @@ import GnoForm from '~/components/forms/GnoForm'
import AddressInput from '~/components/forms/AddressInput'
import Col from '~/components/layout/Col'
import Button from '~/components/layout/Button'
import ScanQRModal from '~/components/ScanQRModal'
import Block from '~/components/layout/Block'
import Img from '~/components/layout/Img'
import Hairline from '~/components/layout/Hairline'
import ButtonLink from '~/components/layout/ButtonLink'
import Field from '~/components/forms/Field'
import TextField from '~/components/forms/TextField'
import TextareaField from '~/components/forms/TextareaField'
import {
composeValidators,
mustBeFloat,
maxValue,
mustBeEthereumContractAddress,
composeValidators, mustBeFloat, maxValue, mustBeEthereumContractAddress,
} from '~/components/forms/validator'
import SafeInfo from '~/routes/safe/components/Balances/SendModal/SafeInfo'
import QRIcon from '~/assets/icons/qrcode.svg'
import ArrowDown from '../assets/arrow-down.svg'
import { styles } from './style'
@ -47,12 +47,21 @@ const SendCustomTx = ({
onSubmit,
initialValues,
}: Props) => {
const [qrModalOpen, setQrModalOpen] = useState<boolean>(false)
const handleSubmit = (values: Object) => {
if (values.data || values.value) {
onSubmit(values)
}
}
const openQrModal = () => {
setQrModalOpen(true)
}
const closeQrModal = () => {
setQrModalOpen(false)
}
const formMutators = {
setMax: (args, state, utils) => {
utils.changeValue(state, 'value', () => ethBalance)
@ -78,6 +87,17 @@ const SendCustomTx = ({
{(...args) => {
const mutators = args[3]
const handleScan = (value) => {
let scannedAddress = value
if (scannedAddress.startsWith('ethereum:')) {
scannedAddress = scannedAddress.replace('ethereum:', '')
}
mutators.setRecipient(scannedAddress)
closeQrModal()
}
return (
<>
<Block className={classes.formContainer}>
@ -96,7 +116,7 @@ const SendCustomTx = ({
</Col>
</Row>
<Row margin="md">
<Col xs={12}>
<Col xs={11}>
<AddressInput
name="recipientAddress"
component={TextField}
@ -107,6 +127,18 @@ const SendCustomTx = ({
validators={[mustBeEthereumContractAddress]}
/>
</Col>
<Col xs={1} center="xs" middle="xs" className={classes}>
<Img
src={QRIcon}
className={classes.qrCodeBtn}
role="button"
height={20}
alt="Scan QR"
onClick={() => {
openQrModal()
}}
/>
</Col>
</Row>
<Row margin="xs">
<Col between="lg">
@ -124,10 +156,7 @@ const SendCustomTx = ({
name="value"
component={TextField}
type="text"
validate={composeValidators(
mustBeFloat,
maxValue(ethBalance),
)}
validate={composeValidators(mustBeFloat, maxValue(ethBalance))}
placeholder="Value*"
text="Value*"
className={classes.addressInput}
@ -164,6 +193,7 @@ const SendCustomTx = ({
Review
</Button>
</Row>
{qrModalOpen && <ScanQRModal isOpen={qrModalOpen} onScan={handleScan} onClose={closeQrModal} />}
</>
)
}}

View File

@ -21,6 +21,9 @@ export const styles = () => ({
height: '35px',
width: '35px',
},
qrCodeBtn: {
cursor: 'pointer',
},
formContainer: {
padding: `${md} ${lg}`,
},

View File

@ -1,5 +1,5 @@
// @flow
import React from 'react'
import React, { useState } from 'react'
import { List } from 'immutable'
import { withStyles } from '@material-ui/core/styles'
import { OnChange } from 'react-final-form-listeners'
@ -13,6 +13,7 @@ import AddressInput from '~/components/forms/AddressInput'
import Col from '~/components/layout/Col'
import Button from '~/components/layout/Button'
import Block from '~/components/layout/Block'
import Img from '~/components/layout/Img'
import Hairline from '~/components/layout/Hairline'
import ButtonLink from '~/components/layout/ButtonLink'
import Field from '~/components/forms/Field'
@ -23,7 +24,9 @@ import {
} from '~/components/forms/validator'
import TokenSelectField from '~/routes/safe/components/Balances/SendModal/screens/SendFunds/TokenSelectField'
import SafeInfo from '~/routes/safe/components/Balances/SendModal/SafeInfo'
import ScanQRModal from '~/components/ScanQRModal'
import ArrowDown from '../assets/arrow-down.svg'
import QRIcon from '~/assets/icons/qrcode.svg'
import { styles } from './style'
type Props = {
@ -39,6 +42,20 @@ type Props = {
initialValues: Object,
}
const formMutators = {
setMax: (args, state, utils) => {
const { token } = state.formState.values
utils.changeValue(state, 'amount', () => token && token.balance)
},
onTokenChange: (args, state, utils) => {
utils.changeValue(state, 'amount', () => '')
},
setRecipient: (args, state, utils) => {
utils.changeValue(state, 'recipientAddress', () => args[0])
},
}
const SendFunds = ({
classes,
onClose,
@ -51,22 +68,18 @@ const SendFunds = ({
initialValues,
onSubmit,
}: Props) => {
const [qrModalOpen, setQrModalOpen] = useState<boolean>(false)
const handleSubmit = (values) => {
onSubmit(values)
}
const formMutators = {
setMax: (args, state, utils) => {
const { token } = state.formState.values
const openQrModal = () => {
setQrModalOpen(true)
}
utils.changeValue(state, 'amount', () => token && token.balance)
},
onTokenChange: (args, state, utils) => {
utils.changeValue(state, 'amount', () => '')
},
setRecipient: (args, state, utils) => {
utils.changeValue(state, 'recipientAddress', () => args[0])
},
const closeQrModal = () => {
setQrModalOpen(false)
}
return (
@ -86,6 +99,18 @@ const SendFunds = ({
const formState = args[2]
const mutators = args[3]
const { token } = formState.values
const handleScan = (value) => {
let scannedAddress = value
if (scannedAddress.startsWith('ethereum:')) {
scannedAddress = scannedAddress.replace('ethereum:', '')
}
mutators.setRecipient(scannedAddress)
closeQrModal()
}
return (
<>
<Block className={classes.formContainer}>
@ -104,7 +129,7 @@ const SendFunds = ({
</Col>
</Row>
<Row margin="md">
<Col xs={12}>
<Col xs={11}>
<AddressInput
name="recipientAddress"
component={TextField}
@ -114,6 +139,18 @@ const SendFunds = ({
fieldMutator={mutators.setRecipient}
/>
</Col>
<Col xs={1} center="xs" middle="xs" className={classes}>
<Img
src={QRIcon}
className={classes.qrCodeBtn}
role="button"
height={20}
alt="Scan QR"
onClick={() => {
openQrModal()
}}
/>
</Col>
</Row>
<Row margin="sm">
<Col>
@ -175,6 +212,7 @@ const SendFunds = ({
Review
</Button>
</Row>
{qrModalOpen && <ScanQRModal isOpen={qrModalOpen} onScan={handleScan} onClose={closeQrModal} />}
</>
)
}}

View File

@ -21,6 +21,9 @@ export const styles = () => ({
height: '35px',
width: '35px',
},
qrCodeBtn: {
cursor: 'pointer',
},
formContainer: {
padding: `${md} ${lg}`,
},