Browse Source

Add QrCode Reader for RecipientAddress

master
Loëck Vézien 7 years ago
parent
commit
6391ec930a
No known key found for this signature in database GPG Key ID: CBCDCE384E853AC4
  1. 1
      package.json
  2. 87
      src/components/RecipientAddress/index.js
  3. 9
      src/components/RecipientAddress/stories.js
  4. 1
      src/components/base/Icon/index.js
  5. 2
      src/components/modals/Receive.js
  6. 66
      src/components/modals/Send.js
  7. 1
      static/i18n/en/translation.yml
  8. 1
      static/i18n/fr/translation.yml
  9. 29
      yarn.lock

1
package.json

@ -71,6 +71,7 @@
"react-i18next": "^7.3.4",
"react-mortal": "^3.0.1",
"react-motion": "^0.5.2",
"react-qr-reader": "^2.0.1",
"react-redux": "^5.0.6",
"react-router": "^4.2.0",
"react-router-dom": "^4.2.2",

87
src/components/RecipientAddress/index.js

@ -0,0 +1,87 @@
// @flow
import React, { PureComponent, Fragment } from 'react'
import styled from 'styled-components'
import QrReader from 'react-qr-reader'
import noop from 'lodash/noop'
import Box from 'components/base/Box'
import Icon from 'components/base/Icon'
import Input from 'components/base/Input'
const IconQrCode = ({ onClick }: { onClick: Function }) => (
<Box color="steel" style={{ position: 'absolute', right: 15 }}>
<Icon fontSize={30} name="qrcode" style={{ cursor: 'pointer' }} onClick={onClick} />
</Box>
)
const InputAddress = styled(Input).attrs({
type: 'text',
})`
padding-right: ${p => p.withQrCode && 55};
`
const WrapperQrCode = styled(Box)`
margin-top: 10px;
position: absolute;
right: 15px;
top: 100%;
`
type Props = {
value: string,
onChange: Function,
qrCodeSize: number,
withQrCode: boolean,
}
type State = {
qrReaderOpened: boolean,
}
class RecipientAddress extends PureComponent<Props, State> {
static defaultProps = {
value: '',
onChange: noop,
qrCodeSize: 200,
withQrCode: true,
}
state = {
qrReaderOpened: false,
}
handleClickQrCode = () =>
this.setState(prev => ({
qrReaderOpened: !prev.qrReaderOpened,
}))
handleScanQrCode = (data: string) => data !== null && this.props.onChange(data)
render() {
const { onChange, qrCodeSize, withQrCode, value } = this.props
const { qrReaderOpened } = this.state
return (
<Box relative justify="center">
<InputAddress value={value} withQrCode={withQrCode} onChange={onChange} />
{withQrCode && (
<Fragment>
<IconQrCode onClick={this.handleClickQrCode} />
{qrReaderOpened && (
<WrapperQrCode>
<QrReader
onScan={this.handleScanQrCode}
onError={noop}
style={{ height: qrCodeSize, width: qrCodeSize }}
/>
</WrapperQrCode>
)}
</Fragment>
)}
</Box>
)
}
}
export default RecipientAddress

9
src/components/RecipientAddress/stories.js

@ -0,0 +1,9 @@
import React from 'react'
import { storiesOf } from '@storybook/react'
import { boolean } from '@storybook/addon-knobs'
import RecipientAddress from 'components/RecipientAddress'
const stories = storiesOf('RecipientAddress', module)
stories.add('basic', () => <RecipientAddress withQrCode={boolean('withQrCode', true)} />)

1
src/components/base/Icon/index.js

@ -8,6 +8,7 @@ import FontAwesomeIcon from '@fortawesome/react-fontawesome'
const Container = styled.span`
${fontSize};
${color};
display: inline-flex;
position: relative;
`

2
src/components/modals/Receive.js

@ -65,7 +65,7 @@ class ReceiveModal extends PureComponent<Props, State> {
return (
<ModalBody onClose={onClose} flow={3}>
<Text fontSize={4} color="steel">
{t('receive.modalTitle')}
{t('receive.title')}
</Text>
<Box flow={1}>
<Label>Account</Label>

66
src/components/modals/Send.js

@ -1,23 +1,24 @@
// @flow
import React, { Fragment, PureComponent } from 'react'
import styled from 'styled-components'
import { translate } from 'react-i18next'
import get from 'lodash/get'
import type { T } from 'types/common'
import { MODAL_SEND } from 'constants'
import Box from 'components/base/Box'
import Button from 'components/base/Button'
import Input from 'components/base/Input'
import Label from 'components/base/Label'
import Modal, { ModalBody } from 'components/base/Modal'
import RecipientAddress from 'components/RecipientAddress'
import SelectAccount from 'components/SelectAccount'
const Label = styled.label`
display: block;
text-transform: uppercase;
`
import Text from 'components/base/Text'
const Steps = {
amount: (props: Object) => (
amount: ({ t, ...props }: Object) => (
<form
onSubmit={(e: SyntheticEvent<HTMLFormElement>) => {
e.preventDefault()
@ -33,20 +34,33 @@ const Steps = {
props.onChangeStep('summary')
}}
>
<div>amount</div>
<div>
<Label>Account to debit</Label>
<SelectAccount onChange={props.onChangeInput('account')} value={props.value.account} />
</div>
<div>
<Label>Recipient address</Label>
<Input onChange={props.onChangeInput('address')} value={props.value.address} />
</div>
<div>
<Label>Amount</Label>
<Input onChange={props.onChangeInput('amount')} value={props.value.amount} />
</div>
<Button type="submit">Next</Button>
<Box flow={3}>
<Text fontSize={4} color="steel">
{t('send.title')}
</Text>
<Box flow={1}>
<Label>Account to debit</Label>
<SelectAccount onChange={props.onChangeInput('account')} value={props.value.account} />
</Box>
<Box flow={1}>
<Label>Recipient address</Label>
<RecipientAddress onChange={props.onChangeInput('address')} value={props.value.address} />
</Box>
<Box flow={1}>
<Label>Amount</Label>
<Input onChange={props.onChangeInput('amount')} value={props.value.amount} />
</Box>
<Box horizontal align="center">
<Box grow>
<Text>Cancel</Text>
</Box>
<Box justify="flex-end">
<Button type="submit" primary>
Next
</Button>
</Box>
</Box>
</Box>
</form>
),
summary: (props: Object) => (
@ -72,6 +86,10 @@ type State = {
step: Step,
}
type Props = {
t: T,
}
const defaultState = {
inputValue: {
account: null,
@ -81,13 +99,14 @@ const defaultState = {
step: 'amount',
}
class Send extends PureComponent<{}, State> {
class Send extends PureComponent<Props, State> {
state = {
...defaultState,
}
getStepProps(data: any) {
const { inputValue, step } = this.state
const { t } = this.props
const props = (predicate, props) => (predicate ? props : {})
@ -103,6 +122,7 @@ class Send extends PureComponent<{}, State> {
value: inputValue,
}),
onChangeStep: this.handleChangeStep,
t,
}
}
@ -146,4 +166,4 @@ class Send extends PureComponent<{}, State> {
}
}
export default Send
export default translate()(Send)

1
static/i18n/en/translation.yml

@ -18,7 +18,6 @@ send:
receive:
title: Receive
modalTitle: Receive funds
addAccount:
title: Add account

1
static/i18n/fr/translation.yml

@ -18,7 +18,6 @@ send:
receive:
title: Recevoir
modalTitle: Recevoir des fonds
addAccount:
title: Ajouter un compte

29
yarn.lock

@ -5409,6 +5409,10 @@ jsprim@^1.2.2:
json-schema "0.2.3"
verror "1.10.0"
"jsqr@git+https://github.com/cozmo/jsQR.git":
version "1.0.1"
resolved "git+https://github.com/cozmo/jsQR.git#1fb946a235abdc7709f04cd0e4aa316a3b6eae70"
jsx-ast-utils@^2.0.0, jsx-ast-utils@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-2.0.1.tgz#e801b1b39985e20fffc87b40e3748080e2dcac7f"
@ -7401,6 +7405,14 @@ react-portal@^4.0.0:
dependencies:
prop-types "^15.5.8"
react-qr-reader@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/react-qr-reader/-/react-qr-reader-2.0.1.tgz#f7be785e8c880d7e68423fc129802994f70b6b58"
dependencies:
jsqr "https://github.com/cozmo/jsQR.git"
prop-types "^15.5.8"
webrtc-adapter "^5.0.6"
react-redux@^5.0.5, react-redux@^5.0.6:
version "5.0.6"
resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-5.0.6.tgz#23ed3a4f986359d68b5212eaaa681e60d6574946"
@ -7929,6 +7941,12 @@ ripemd160@^2.0.0, ripemd160@^2.0.1:
hash-base "^2.0.0"
inherits "^2.0.1"
rtcpeerconnection-shim@^1.1.13:
version "1.2.5"
resolved "https://registry.yarnpkg.com/rtcpeerconnection-shim/-/rtcpeerconnection-shim-1.2.5.tgz#bfbae97e265ad05377e6fed1cfcb7f5880ce6000"
dependencies:
sdp "^2.2.0"
run-async@^2.2.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0"
@ -7988,6 +8006,10 @@ schema-utils@^0.4.2:
ajv "^5.0.0"
ajv-keywords "^2.1.0"
sdp@^2.2.0, sdp@^2.3.0:
version "2.5.0"
resolved "https://registry.yarnpkg.com/sdp/-/sdp-2.5.0.tgz#b15a0b1dfd0a38f6a8c780e58f8c8fe73c29ffe5"
select-hose@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca"
@ -9282,6 +9304,13 @@ webpack@^3.10.0:
webpack-sources "^1.0.1"
yargs "^8.0.2"
webrtc-adapter@^5.0.6:
version "5.0.6"
resolved "https://registry.yarnpkg.com/webrtc-adapter/-/webrtc-adapter-5.0.6.tgz#7946fca194dadf869bb6c8cae1011dfda03f40c7"
dependencies:
rtcpeerconnection-shim "^1.1.13"
sdp "^2.3.0"
websocket-driver@>=0.5.1:
version "0.7.0"
resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.0.tgz#0caf9d2d755d93aee049d4bdd0d3fe2cca2a24eb"

Loading…
Cancel
Save