add qr scanner to send funds/send custom tx flows
This commit is contained in:
parent
c38325bca5
commit
a113f2321d
|
@ -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'
|
||||
|
||||
|
|
|
@ -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} />}
|
||||
</>
|
||||
)
|
||||
}}
|
||||
|
|
|
@ -21,6 +21,9 @@ export const styles = () => ({
|
|||
height: '35px',
|
||||
width: '35px',
|
||||
},
|
||||
qrCodeBtn: {
|
||||
cursor: 'pointer',
|
||||
},
|
||||
formContainer: {
|
||||
padding: `${md} ${lg}`,
|
||||
},
|
||||
|
|
|
@ -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} />}
|
||||
</>
|
||||
)
|
||||
}}
|
||||
|
|
|
@ -21,6 +21,9 @@ export const styles = () => ({
|
|||
height: '35px',
|
||||
width: '35px',
|
||||
},
|
||||
qrCodeBtn: {
|
||||
cursor: 'pointer',
|
||||
},
|
||||
formContainer: {
|
||||
padding: `${md} ${lg}`,
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue