From 6391ec930a44bf7775d7cc4e1f0c22fd40aa1b8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=ABck=20V=C3=A9zien?= Date: Wed, 31 Jan 2018 13:37:27 +0100 Subject: [PATCH] Add QrCode Reader for RecipientAddress --- package.json | 1 + src/components/RecipientAddress/index.js | 87 ++++++++++++++++++++++ src/components/RecipientAddress/stories.js | 9 +++ src/components/base/Icon/index.js | 1 + src/components/modals/Receive.js | 2 +- src/components/modals/Send.js | 66 ++++++++++------ static/i18n/en/translation.yml | 1 - static/i18n/fr/translation.yml | 1 - yarn.lock | 29 ++++++++ 9 files changed, 171 insertions(+), 26 deletions(-) create mode 100644 src/components/RecipientAddress/index.js create mode 100644 src/components/RecipientAddress/stories.js diff --git a/package.json b/package.json index ff1b4d03..d1a38e03 100644 --- a/package.json +++ b/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", diff --git a/src/components/RecipientAddress/index.js b/src/components/RecipientAddress/index.js new file mode 100644 index 00000000..575e803f --- /dev/null +++ b/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 }) => ( + + + +) + +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 { + 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 ( + + + {withQrCode && ( + + + {qrReaderOpened && ( + + + + )} + + )} + + ) + } +} + +export default RecipientAddress diff --git a/src/components/RecipientAddress/stories.js b/src/components/RecipientAddress/stories.js new file mode 100644 index 00000000..2cb3e325 --- /dev/null +++ b/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', () => ) diff --git a/src/components/base/Icon/index.js b/src/components/base/Icon/index.js index 2ef9d956..12af7f54 100644 --- a/src/components/base/Icon/index.js +++ b/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; ` diff --git a/src/components/modals/Receive.js b/src/components/modals/Receive.js index 6abc24cf..2271f9c9 100644 --- a/src/components/modals/Receive.js +++ b/src/components/modals/Receive.js @@ -65,7 +65,7 @@ class ReceiveModal extends PureComponent { return ( - {t('receive.modalTitle')} + {t('receive.title')} diff --git a/src/components/modals/Send.js b/src/components/modals/Send.js index b9507eba..cec64a01 100644 --- a/src/components/modals/Send.js +++ b/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) => (
) => { e.preventDefault() @@ -33,20 +34,33 @@ const Steps = { props.onChangeStep('summary') }} > -
amount
-
- - -
-
- - -
-
- - -
- + + + {t('send.title')} + + + + + + + + + + + + + + + + Cancel + + + + + +
), 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 { 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) diff --git a/static/i18n/en/translation.yml b/static/i18n/en/translation.yml index 8d8eda6e..cfbf4e8c 100644 --- a/static/i18n/en/translation.yml +++ b/static/i18n/en/translation.yml @@ -18,7 +18,6 @@ send: receive: title: Receive - modalTitle: Receive funds addAccount: title: Add account diff --git a/static/i18n/fr/translation.yml b/static/i18n/fr/translation.yml index 5a4039ff..6d984c27 100644 --- a/static/i18n/fr/translation.yml +++ b/static/i18n/fr/translation.yml @@ -18,7 +18,6 @@ send: receive: title: Recevoir - modalTitle: Recevoir des fonds addAccount: title: Ajouter un compte diff --git a/yarn.lock b/yarn.lock index 8bdda5fd..ea7903f3 100644 --- a/yarn.lock +++ b/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"