From a113f2321dd0a9a99abe1e2387e7e94900bc6068 Mon Sep 17 00:00:00 2001 From: Mikhail Mikheev Date: Fri, 4 Oct 2019 16:16:53 +0400 Subject: [PATCH] add qr scanner to send funds/send custom tx flows --- .../ScanQRModal/index.jsx | 0 .../ScanQRModal/style.js | 0 .../ScanQRModal/utils.js | 0 .../SafeOwnersConfirmationsForm/index.jsx | 2 +- .../SendModal/screens/SendCustomTx/index.jsx | 50 ++++++++++++--- .../SendModal/screens/SendCustomTx/style.js | 3 + .../SendModal/screens/SendFunds/index.jsx | 64 +++++++++++++++---- .../SendModal/screens/SendFunds/style.js | 3 + 8 files changed, 98 insertions(+), 24 deletions(-) rename src/{routes/open/components/SafeOwnersConfirmationsForm => components}/ScanQRModal/index.jsx (100%) rename src/{routes/open/components/SafeOwnersConfirmationsForm => components}/ScanQRModal/style.js (100%) rename src/{routes/open/components/SafeOwnersConfirmationsForm => components}/ScanQRModal/utils.js (100%) diff --git a/src/routes/open/components/SafeOwnersConfirmationsForm/ScanQRModal/index.jsx b/src/components/ScanQRModal/index.jsx similarity index 100% rename from src/routes/open/components/SafeOwnersConfirmationsForm/ScanQRModal/index.jsx rename to src/components/ScanQRModal/index.jsx diff --git a/src/routes/open/components/SafeOwnersConfirmationsForm/ScanQRModal/style.js b/src/components/ScanQRModal/style.js similarity index 100% rename from src/routes/open/components/SafeOwnersConfirmationsForm/ScanQRModal/style.js rename to src/components/ScanQRModal/style.js diff --git a/src/routes/open/components/SafeOwnersConfirmationsForm/ScanQRModal/utils.js b/src/components/ScanQRModal/utils.js similarity index 100% rename from src/routes/open/components/SafeOwnersConfirmationsForm/ScanQRModal/utils.js rename to src/components/ScanQRModal/utils.js diff --git a/src/routes/open/components/SafeOwnersConfirmationsForm/index.jsx b/src/routes/open/components/SafeOwnersConfirmationsForm/index.jsx index 54b6ac95..d1ac6441 100644 --- a/src/routes/open/components/SafeOwnersConfirmationsForm/index.jsx +++ b/src/routes/open/components/SafeOwnersConfirmationsForm/index.jsx @@ -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' diff --git a/src/routes/safe/components/Balances/SendModal/screens/SendCustomTx/index.jsx b/src/routes/safe/components/Balances/SendModal/screens/SendCustomTx/index.jsx index b36d895e..aa58ddd0 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/SendCustomTx/index.jsx +++ b/src/routes/safe/components/Balances/SendModal/screens/SendCustomTx/index.jsx @@ -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(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 ( <> @@ -96,7 +116,7 @@ const SendCustomTx = ({ - + + + Scan QR { + openQrModal() + }} + /> + @@ -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 + {qrModalOpen && } ) }} diff --git a/src/routes/safe/components/Balances/SendModal/screens/SendCustomTx/style.js b/src/routes/safe/components/Balances/SendModal/screens/SendCustomTx/style.js index 96a1149e..38f2a9e5 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/SendCustomTx/style.js +++ b/src/routes/safe/components/Balances/SendModal/screens/SendCustomTx/style.js @@ -21,6 +21,9 @@ export const styles = () => ({ height: '35px', width: '35px', }, + qrCodeBtn: { + cursor: 'pointer', + }, formContainer: { padding: `${md} ${lg}`, }, diff --git a/src/routes/safe/components/Balances/SendModal/screens/SendFunds/index.jsx b/src/routes/safe/components/Balances/SendModal/screens/SendFunds/index.jsx index 0d342252..68d9658b 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/SendFunds/index.jsx +++ b/src/routes/safe/components/Balances/SendModal/screens/SendFunds/index.jsx @@ -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(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 ( <> @@ -104,7 +129,7 @@ const SendFunds = ({ - + + + Scan QR { + openQrModal() + }} + /> + @@ -175,6 +212,7 @@ const SendFunds = ({ Review + {qrModalOpen && } ) }} diff --git a/src/routes/safe/components/Balances/SendModal/screens/SendFunds/style.js b/src/routes/safe/components/Balances/SendModal/screens/SendFunds/style.js index 31d3c991..85ddeac7 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/SendFunds/style.js +++ b/src/routes/safe/components/Balances/SendModal/screens/SendFunds/style.js @@ -21,6 +21,9 @@ export const styles = () => ({ height: '35px', width: '35px', }, + qrCodeBtn: { + cursor: 'pointer', + }, formContainer: { padding: `${md} ${lg}`, },