Browse Source

Move to Step 2 if we open modal in Account Page

master
Loëck Vézien 7 years ago
parent
commit
2bfa6c1512
No known key found for this signature in database GPG Key ID: CBCDCE384E853AC4
  1. 2
      package.json
  2. 51
      src/components/Breadcrumb/Step.js
  3. 37
      src/components/Breadcrumb/index.js
  4. 30
      src/components/Breadcrumb/stories.js
  5. 2
      src/components/DeviceConfirm/index.js
  6. 1
      src/components/base/Modal/ModalBody.js
  7. 24
      src/components/base/Modal/index.js
  8. 3
      src/components/base/QRCode/index.js
  9. 25
      src/components/modals/Receive/03-step-confirm-address.js
  10. 2
      src/components/modals/Receive/04-step-receive-funds.js
  11. 93
      src/components/modals/Receive/index.js
  12. 2
      src/components/modals/StepConnectDevice.js
  13. 6
      yarn.lock

2
package.json

@ -59,7 +59,7 @@
"cross-env": "^5.1.4", "cross-env": "^5.1.4",
"d3": "^5.0.0", "d3": "^5.0.0",
"debug": "^3.1.0", "debug": "^3.1.0",
"downshift": "^1.31.4", "downshift": "^1.31.6",
"electron-store": "^1.3.0", "electron-store": "^1.3.0",
"electron-updater": "^2.21.4", "electron-updater": "^2.21.4",
"fuse.js": "^3.2.0", "fuse.js": "^3.2.0",

51
src/components/Breadcrumb/Step.js

@ -1,6 +1,6 @@
// @flow // @flow
import React, { Fragment } from 'react' import React from 'react'
import styled from 'styled-components' import styled from 'styled-components'
import Box from 'components/base/Box' import Box from 'components/base/Box'
@ -8,9 +8,10 @@ import Box from 'components/base/Box'
const RADIUS = 17 const RADIUS = 17
const Wrapper = styled(Box).attrs({ const Wrapper = styled(Box).attrs({
align: 'center', alignItems: 'center',
justify: 'center',
color: p => (p.isActive ? 'wallet' : 'grey'), color: p => (p.isActive ? 'wallet' : 'grey'),
grow: true,
justifyContent: 'center',
})` })`
width: ${RADIUS}px; width: ${RADIUS}px;
flex-shrink: 0; flex-shrink: 0;
@ -19,8 +20,8 @@ const Wrapper = styled(Box).attrs({
` `
const Number = styled(Box).attrs({ const Number = styled(Box).attrs({
align: 'center', alignItems: 'center',
justify: 'center', justifyContent: 'center',
color: 'white', color: 'white',
bg: p => (p.isActive ? 'wallet' : 'fog'), bg: p => (p.isActive ? 'wallet' : 'fog'),
ff: 'Rubik|Regular', ff: 'Rubik|Regular',
@ -33,56 +34,28 @@ const Number = styled(Box).attrs({
width: ${RADIUS}px; width: ${RADIUS}px;
` `
const Bar = styled.div`
height: 2px;
background: ${p => p.theme.colors.fog};
flex-grow: 1;
max-width: 100px;
position: relative;
margin-top: -2px;
&:after {
background: ${p => p.theme.colors.pearl};
content: '';
display: block;
left: 0;
right: 0;
top: 0;
bottom: 0;
position: absolute;
background: ${p => p.theme.colors.wallet};
transition: transform ease-in-out 0.4s;
transform-origin: center left;
transform: scaleX(${p => (p.isActive ? 1 : 0)});
}
`
const Label = styled(Box).attrs({ const Label = styled(Box).attrs({
fontSize: 3, fontSize: 3,
ff: 'Museo Sans|Bold', ff: 'Museo Sans|Bold',
})` })`
position: absolute; position: absolute;
margin-top: 27px; margin-top: 23px;
transition: color ease-in-out 0.1s ${p => (p.isActive ? 0.4 : 0)}s; transition: color ease-in-out 0.1s ${p => (p.isActive ? 0.4 : 0)}s;
` `
type Props = { type Props = {
number: number, number: number,
isActive: boolean, isActive: boolean,
isFirst: boolean,
children: any, children: any,
} }
function Step(props: Props) { function Step(props: Props) {
const { number, isActive, isFirst, children } = props const { number, isActive, children } = props
return ( return (
<Fragment> <Wrapper isActive={isActive}>
{!isFirst && <Bar isActive={isActive} />} <Number isActive={isActive}>{number}</Number>
<Wrapper isActive={isActive}> <Label isActive={isActive}>{children}</Label>
<Number isActive={isActive}>{number}</Number> </Wrapper>
<Label isActive={isActive}>{children}</Label>
</Wrapper>
</Fragment>
) )
} }

37
src/components/Breadcrumb/index.js

@ -15,17 +15,44 @@ type Props = {
const Wrapper = styled(Box).attrs({ const Wrapper = styled(Box).attrs({
horizontal: true, horizontal: true,
align: 'center', alignItems: 'center',
justify: 'center', justifyContent: 'center',
relative: true,
})` })`
margin-bottom: 25px; margin-bottom: 25px;
z-index: 2;
`
const Bar = styled.div`
background: ${p => p.theme.colors.fog};
flex-grow: 1;
height: 1px;
left: ${p => p.start}%;
position: absolute;
right: ${p => p.start}%;
top: 8px;
z-index: 1;
&:after {
background: ${p => p.theme.colors.wallet};
bottom: 0;
content: '';
display: block;
left: 0;
position: absolute;
right: ${p => (p.current === 0 ? 0 : `${p.current}%`)};
top: 0;
transition: right ease-in-out 0.4s;
}
` `
class Breadcrumb extends PureComponent<Props> { class Breadcrumb extends PureComponent<Props> {
render() { render() {
const { items, currentStep, ...props } = this.props const { items, currentStep, ...props } = this.props
const itemsLength = items.length
const start = 100 / itemsLength / 2
return ( return (
<Box {...props}> <Box {...props} relative>
<Wrapper> <Wrapper>
{items.map((item, i) => ( {items.map((item, i) => (
<Step <Step
@ -38,6 +65,10 @@ class Breadcrumb extends PureComponent<Props> {
</Step> </Step>
))} ))}
</Wrapper> </Wrapper>
<Bar
start={start}
current={!currentStep ? 100 : 100 - 100 / (itemsLength - 1) * parseInt(currentStep, 10)}
/>
</Box> </Box>
) )
} }

30
src/components/Breadcrumb/stories.js

@ -9,16 +9,22 @@ import Breadcrumb from 'components/Breadcrumb'
const stories = storiesOf('Components', module) const stories = storiesOf('Components', module)
stories.add('Breadcrumb', () => ( stories.add('Breadcrumb', () => (
<Breadcrumb <div
currentStep={number('currentStep', 1, { style={{
min: 1, width: 400,
max: 4, }}
})} >
items={[ <Breadcrumb
{ label: 'Amount' }, currentStep={number('currentStep', 1, {
{ label: 'Summary' }, min: 1,
{ label: 'Secure validation' }, max: 4,
{ label: 'Confirmation' }, })}
]} items={[
/> { label: 'Amount' },
{ label: 'Summary' },
{ label: 'Secure validation' },
{ label: 'Confirmation' },
]}
/>
</div>
)) ))

2
src/components/DeviceConfirm/index.js

@ -49,7 +49,7 @@ const Check = ({ notValid }: { notValid: boolean }) => (
const PushButton = styled(Box)` const PushButton = styled(Box)`
background: linear-gradient(to bottom, #ffffff, ${p => p.theme.colors.wallet}); background: linear-gradient(to bottom, #ffffff, ${p => p.theme.colors.wallet});
bottom: 53px; bottom: 48px;
height: 28px; height: 28px;
left: 205px; left: 205px;
position: absolute; position: absolute;

1
src/components/base/Modal/ModalBody.js

@ -62,6 +62,7 @@ const CloseContainer = styled(Box).attrs({
position: absolute; position: absolute;
top: 0; top: 0;
right: 0; right: 0;
z-index: 1;
&:hover { &:hover {
color: ${p => p.theme.colors.grey}; color: ${p => p.theme.colors.grey};

24
src/components/base/Modal/index.js

@ -28,11 +28,20 @@ const springConfig = {
const mapStateToProps: Function = ( const mapStateToProps: Function = (
state, state,
{ name, isOpened }: { name: string, isOpened?: boolean }, { name, isOpened, onBeforeOpen }: { name: string, isOpened?: boolean, onBeforeOpen: Function },
): Object => ({ ): Object => {
isOpened: isOpened || (name && isModalOpened(state, name)), const data = getModalData(state, name)
data: getModalData(state, name), const modalOpened = isOpened || (name && isModalOpened(state, name))
})
if (onBeforeOpen) {
onBeforeOpen({ data, isOpened: modalOpened })
}
return {
isOpened: modalOpened,
data,
}
}
const mapDispatchToProps: Function = (dispatch, { name, onClose = noop }): Object => ({ const mapDispatchToProps: Function = (dispatch, { name, onClose = noop }): Object => ({
onClose: name onClose: name
@ -98,12 +107,12 @@ class Pure extends Component<any> {
} }
type Props = { type Props = {
data?: any,
isOpened?: boolean, isOpened?: boolean,
onClose: Function, onClose: Function,
onHide?: Function, onHide?: Function,
preventBackdropClick?: boolean, preventBackdropClick?: boolean,
render: Function, render: Function,
data?: any,
} }
export class Modal extends Component<Props> { export class Modal extends Component<Props> {
@ -138,6 +147,7 @@ export class Modal extends Component<Props> {
domWrapper.focus() domWrapper.focus()
} }
} }
if (didClose) { if (didClose) {
if (this._lastFocusedElement) { if (this._lastFocusedElement) {
this._lastFocusedElement.focus() this._lastFocusedElement.focus()
@ -149,7 +159,7 @@ export class Modal extends Component<Props> {
_lastFocusedElement = null _lastFocusedElement = null
render() { render() {
const { preventBackdropClick, isOpened, onClose, onHide, render, data } = this.props const { preventBackdropClick, isOpened, onHide, render, data, onClose } = this.props
return ( return (
<Mortal <Mortal

3
src/components/base/QRCode/index.js

@ -28,6 +28,9 @@ class QRCode extends PureComponent<Props> {
qrcode.toCanvas(this._canvas, data, { qrcode.toCanvas(this._canvas, data, {
width: size, width: size,
margin: 0, margin: 0,
color: {
light: '#ffffff00', // transparent background
},
}) })
} }

25
src/components/modals/Receive/03-step-confirm-address.js

@ -30,7 +30,7 @@ const Text = styled(Box).attrs({
` `
type Props = { type Props = {
account: Account, account: Account | null,
addressVerified: null | boolean, addressVerified: null | boolean,
device: Device | null, device: Device | null,
onCheck: Function, onCheck: Function,
@ -41,16 +41,19 @@ export default (props: Props) => (
<Container> <Container>
<Title>{props.t('receive:steps.confirmAddress.action')}</Title> <Title>{props.t('receive:steps.confirmAddress.action')}</Title>
<Text>{props.t('receive:steps.confirmAddress.text')}</Text> <Text>{props.t('receive:steps.confirmAddress.text')}</Text>
<CurrentAddress addressVerified={props.addressVerified} account={props.account} /> {props.account && (
{props.device && ( <CurrentAddress addressVerified={props.addressVerified} account={props.account} />
<Box mb={2}>
<DeviceCheckAddress
account={props.account}
device={props.device}
onCheck={props.onCheck}
render={({ isVerified }) => <DeviceConfirm notValid={isVerified === false} />}
/>
</Box>
)} )}
{props.device &&
props.account && (
<Box mb={2}>
<DeviceCheckAddress
account={props.account}
device={props.device}
onCheck={props.onCheck}
render={({ isVerified }) => <DeviceConfirm notValid={isVerified === false} />}
/>
</Box>
)}
</Container> </Container>
) )

2
src/components/modals/Receive/04-step-receive-funds.js

@ -12,7 +12,7 @@ import SelectAccount from 'components/SelectAccount'
import RequestAmount from 'components/RequestAmount' import RequestAmount from 'components/RequestAmount'
type Props = { type Props = {
account: Account, account: Account | null,
addressVerified: null | boolean, addressVerified: null | boolean,
amount: string | number, amount: string | number,
onChangeAmount: Function, onChangeAmount: Function,

93
src/components/modals/Receive/index.js

@ -3,9 +3,8 @@
import React, { Fragment, PureComponent } from 'react' import React, { Fragment, PureComponent } from 'react'
import styled from 'styled-components' import styled from 'styled-components'
import { translate } from 'react-i18next' import { translate } from 'react-i18next'
import get from 'lodash/get'
import type { Account } from '@ledgerhq/wallet-common/lib/types'
import type { Account } from '@ledgerhq/wallet-common/lib/types'
import type { T, Device } from 'types/common' import type { T, Device } from 'types/common'
import { MODAL_RECEIVE } from 'config/constants' import { MODAL_RECEIVE } from 'config/constants'
@ -64,11 +63,11 @@ class ReceiveModal extends PureComponent<Props, State> {
_steps = GET_STEPS(this.props.t) _steps = GET_STEPS(this.props.t)
canNext = acc => { canNext = () => {
const { stepIndex } = this.state const { account, stepIndex } = this.state
if (stepIndex === 0) { if (stepIndex === 0) {
return acc !== null return account !== null
} }
if (stepIndex === 1) { if (stepIndex === 1) {
@ -160,14 +159,24 @@ class ReceiveModal extends PureComponent<Props, State> {
handleChangeAmount = amount => this.setState({ amount }) handleChangeAmount = amount => this.setState({ amount })
handleBeforeOpenModal = ({ data }) => {
const { account } = this.state
if (data && data.account && !account) {
this.setState({
account: data.account,
stepIndex: 1,
})
}
}
handleSkipStep = () => handleSkipStep = () =>
this.setState({ this.setState({
addressVerified: false, addressVerified: false,
stepIndex: this._steps.length - 1, // last step stepIndex: this._steps.length - 1, // last step
}) })
renderStep = acc => { renderStep = () => {
const { amount, addressVerified, deviceSelected, stepIndex } = this.state const { account, amount, addressVerified, deviceSelected, stepIndex } = this.state
const { t } = this.props const { t } = this.props
const step = this._steps[stepIndex] const step = this._steps[stepIndex]
if (!step) { if (!step) {
@ -179,12 +188,12 @@ class ReceiveModal extends PureComponent<Props, State> {
const stepProps = { const stepProps = {
t, t,
account: acc, account,
...props(stepIndex === 0, { ...props(stepIndex === 0, {
onChangeAccount: this.handleChangeAccount, onChangeAccount: this.handleChangeAccount,
}), }),
...props(stepIndex === 1, { ...props(stepIndex === 1, {
accountName: acc ? acc.name : undefined, accountName: account ? account.name : undefined,
deviceSelected, deviceSelected,
onChangeDevice: this.handleChangeDevice, onChangeDevice: this.handleChangeDevice,
onStatusChange: this.handleChangeStatus, onStatusChange: this.handleChangeStatus,
@ -204,7 +213,7 @@ class ReceiveModal extends PureComponent<Props, State> {
return <Comp {...stepProps} /> return <Comp {...stepProps} />
} }
renderButton = acc => { renderButton = () => {
const { t } = this.props const { t } = this.props
const { stepIndex } = this.state const { stepIndex } = this.state
@ -222,7 +231,7 @@ class ReceiveModal extends PureComponent<Props, State> {
onClick = this.handleNextStep onClick = this.handleNextStep
props = { props = {
primary: true, primary: true,
disabled: !this.canNext(acc), disabled: !this.canNext(),
onClick, onClick,
children: t('common:next'), children: t('common:next'),
} }
@ -242,46 +251,44 @@ class ReceiveModal extends PureComponent<Props, State> {
render() { render() {
const { t } = this.props const { t } = this.props
const { stepIndex, account } = this.state const { stepIndex } = this.state
const canClose = this.canClose() const canClose = this.canClose()
const canPrev = this.canPrev() const canPrev = this.canPrev()
return ( return (
<Modal <Modal
preventBackdropClick={!canClose}
name={MODAL_RECEIVE} name={MODAL_RECEIVE}
onBeforeOpen={this.handleBeforeOpenModal}
onHide={this.handleReset} onHide={this.handleReset}
render={({ data, onClose }) => { preventBackdropClick={!canClose}
const acc = account || get(data, 'account', null) render={({ onClose }) => (
return ( <ModalBody onClose={canClose ? onClose : undefined}>
<ModalBody onClose={canClose ? onClose : undefined} deferHeight={330}> <ModalTitle>
<ModalTitle> {canPrev && (
{canPrev && ( <PrevButton onClick={this.handlePrevStep}>
<PrevButton onClick={this.handlePrevStep}> <Box horizontal alignItems="center">
<Box horizontal alignItems="center"> <IconAngleLeft size={16} />
<IconAngleLeft size={16} /> {t('common:back')}
{t('common:back')} </Box>
</Box> </PrevButton>
</PrevButton> )}
)} {t('receive:title')}
{t('receive:title')} </ModalTitle>
</ModalTitle> <ModalContent>
<ModalContent> <Breadcrumb mb={5} currentStep={stepIndex} items={this._steps} />
<Breadcrumb mb={5} currentStep={stepIndex} items={this._steps} /> {this.renderStep()}
{this.renderStep(acc)} </ModalContent>
</ModalContent> {stepIndex !== 3 &&
{stepIndex !== 3 && canClose && (
canClose && ( <ModalFooter>
<ModalFooter> <Box horizontal alignItems="center" justifyContent="flex-end" flow={2}>
<Box horizontal alignItems="center" justifyContent="flex-end" flow={2}> {this.renderButton()}
{this.renderButton(acc)} </Box>
</Box> </ModalFooter>
</ModalFooter> )}
)} </ModalBody>
</ModalBody> )}
)
}}
/> />
) )
} }

2
src/components/modals/StepConnectDevice.js

@ -11,7 +11,7 @@ import DeviceMonit from 'components/DeviceMonitNew'
type Props = { type Props = {
accountName?: string, accountName?: string,
account?: Account, account?: Account | null,
currency?: Currency | null, currency?: Currency | null,
deviceSelected: Device | null, deviceSelected: Device | null,
onChangeDevice: Function, onChangeDevice: Function,

6
yarn.lock

@ -4673,9 +4673,9 @@ dotenv@^5.0.0, dotenv@^5.0.1:
version "5.0.1" version "5.0.1"
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-5.0.1.tgz#a5317459bd3d79ab88cff6e44057a6a3fbb1fcef" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-5.0.1.tgz#a5317459bd3d79ab88cff6e44057a6a3fbb1fcef"
downshift@^1.31.4: downshift@^1.31.6:
version "1.31.4" version "1.31.6"
resolved "https://registry.yarnpkg.com/downshift/-/downshift-1.31.4.tgz#72ab0b8ac4c5801221ed098f97817c70899c9d16" resolved "https://registry.yarnpkg.com/downshift/-/downshift-1.31.6.tgz#467ef5bb81e68d2377c7ed2c602a43f81e68478f"
duplexer2@~0.1.4: duplexer2@~0.1.4:
version "0.1.4" version "0.1.4"

Loading…
Cancel
Save