Browse Source

Merge branch 'master' into walletbridge-send

master
Gaëtan Renaudeau 7 years ago
parent
commit
0836563724
  1. 2
      package.json
  2. 30
      src/components/GlobalSearch.js
  3. 24
      src/components/Onboarding/OnboardingFooter.js
  4. 56
      src/components/Onboarding/helperComponents.js
  5. 12
      src/components/Onboarding/index.js
  6. 62
      src/components/Onboarding/steps/ChooseDevice.js
  7. 33
      src/components/Onboarding/steps/ChoosePIN.js
  8. 89
      src/components/Onboarding/steps/Finish.js
  9. 157
      src/components/Onboarding/steps/Init.js
  10. 79
      src/components/Onboarding/steps/SelectDevice.js
  11. 72
      src/components/Onboarding/steps/SelectPIN.js
  12. 15
      src/components/Onboarding/steps/Start.js
  13. 81
      src/components/Onboarding/steps/WriteSeed.js
  14. 20
      src/components/TopBar.js
  15. 6
      src/components/base/Box/index.js
  16. 32
      src/components/modals/SettingsAccount.js
  17. 79
      src/icons/onboarding/GetStartedLogo.js
  18. 32
      src/icons/onboarding/LedgerBlue.js
  19. 36
      src/icons/onboarding/LedgerNano.js
  20. 75
      src/icons/onboarding/SelectPIN.js
  21. 197
      src/icons/onboarding/WriteSeed.js
  22. 16
      src/reducers/onboarding.js
  23. 2
      src/reducers/settings.js
  24. 1
      static/i18n/en/common.yml
  25. 48
      static/i18n/en/onboarding.yml
  26. 164
      yarn.lock

2
package.json

@ -117,7 +117,7 @@
"electron-builder": "^20.9.0",
"electron-devtools-installer": "^2.2.3",
"electron-rebuild": "^1.7.3",
"electron-webpack": "^2.0.1",
"electron-webpack": "^2.1.0",
"eslint": "^4.19.1",
"eslint-config-airbnb": "^16.1.0",
"eslint-config-prettier": "^2.9.0",

30
src/components/GlobalSearch.js

@ -1,6 +1,6 @@
// @flow
import React, { PureComponent } from 'react'
import React, { PureComponent, Fragment } from 'react'
import styled from 'styled-components'
import type { T } from 'types/common'
@ -29,6 +29,7 @@ type State = {
type Props = {
t: T,
isHidden: boolean,
}
class GlobalSearch extends PureComponent<Props, State> {
@ -55,21 +56,24 @@ class GlobalSearch extends PureComponent<Props, State> {
})
render() {
const { t } = this.props
const { t, isHidden } = this.props
const { isFocused } = this.state
return (
<Container isFocused={isFocused}>
<Box justifyContent="center" onClick={this.focusInput} pr={2}>
<IconSearch size={16} />
</Box>
<Input
placeholder={t('common:search')}
innerRef={input => (this._input = input)}
onBlur={this.handleBlur}
onFocus={this.handleFocus}
isFocused={isFocused}
/>
{!isHidden && (
<Fragment>
<Box justifyContent="center" onClick={this.focusInput} pr={2}>
<IconSearch size={16} />
</Box>
<Input
placeholder={t('common:search')}
innerRef={input => (this._input = input)}
onBlur={this.handleBlur}
onFocus={this.handleFocus}
isFocused={isFocused}
/>
</Fragment>
)}
</Container>
)
}

24
src/components/Onboarding/OnboardingFooter.js

@ -1,11 +1,15 @@
// @flow
import React from 'react'
import styled from 'styled-components'
import { radii } from 'styles/theme'
import type { T } from 'types/common'
import Button from 'components/base/Button'
import Box from 'components/base/Box'
export const OnboardingFooter = styled(Box).attrs({
const Wrapper = styled(Box).attrs({
px: 5,
py: 3,
})`
@ -13,3 +17,21 @@ export const OnboardingFooter = styled(Box).attrs({
border-bottom-left-radius: ${radii[1]}px;
border-bottom-right-radius: ${radii[1]}px;
`
type Props = {
t: T,
nextStep: () => void,
prevStep: () => void,
}
const OnboardingFooter = ({ t, nextStep, prevStep, ...props }: Props) => (
<Wrapper {...props}>
<Button small outline onClick={() => prevStep()}>
{t('common:back')}
</Button>
<Button small primary onClick={() => nextStep()} ml="auto">
{t('common:continue')}
</Button>
</Wrapper>
)
export default OnboardingFooter

56
src/components/Onboarding/helperComponents.js

@ -1,11 +1,13 @@
// @flow
import React from 'react'
import styled from 'styled-components'
import { radii } from 'styles/theme'
import Box from 'components/base/Box'
// GENERAL
export const Title = styled(Box).attrs({
width: 152,
width: 267,
height: 27,
ff: 'Museo Sans|Regular',
fontSize: 7,
@ -13,12 +15,13 @@ export const Title = styled(Box).attrs({
})``
export const Description = styled(Box).attrs({
width: 340,
height: 36,
ff: 'Open Sans|Regular',
fontSize: 4,
width: 714,
height: 48,
ff: 'Museo Sans|Light',
fontSize: 5,
lineHeight: 1.5,
textAlign: 'center',
color: 'smoke',
color: 'grey',
})`
margin: 10px auto 25px;
`
@ -28,6 +31,7 @@ export const Inner = styled(Box).attrs({
flow: 4,
})``
// FOOTER
export const OnboardingFooter = styled(Box).attrs({
px: 5,
py: 3,
@ -36,3 +40,43 @@ export const OnboardingFooter = styled(Box).attrs({
border-bottom-left-radius: ${radii[1]}px;
border-bottom-right-radius: ${radii[1]}px;
`
// INSTRUCTION LIST
type StepType = {
icon: any,
desc: string,
}
export function InstructionStep({ step }: { step: StepType }) {
const { icon, desc } = step
return (
<Box horizontal>
<Box justify="center" color="grey" style={{ width: 26 }}>
{icon}
</Box>
<Box ff="Open Sans|Regular" justify="center" fontSize={4} style={{ paddingLeft: 10 }} shrink>
<InstructionStepDesc>{desc}</InstructionStepDesc>
</Box>
</Box>
)
}
export const InstructionStepDesc = styled(Box).attrs({
ff: 'Open Sans|Regular',
fontSize: 4,
textAlign: 'left',
lineHeight: 1.69,
color: 'smoke',
shrink: 1,
})``
export const IconInstructionStep = styled(Box).attrs({
width: 26,
height: 26,
ff: 'Rubik|Regular',
textAlign: 'center',
fontSize: 3,
color: 'wallet',
})`
border-radius: 100%;
background: #6490f126;
line-height: 2;
`

12
src/components/Onboarding/index.js

@ -21,8 +21,8 @@ import Box from 'components/base/Box'
import Start from './steps/Start'
import InitStep from './steps/Init'
import OnboardingBreadcrumb from './OnboardingBreadcrumb'
import ChooseDevice from './steps/ChooseDevice'
import ChoosePIN from './steps/ChoosePIN'
import SelectDevice from './steps/SelectDevice'
import SelectPIN from './steps/SelectPIN'
import WriteSeed from './steps/WriteSeed'
import GenuineCheck from './steps/GenuineCheck'
import SetPassword from './steps/SetPassword'
@ -31,8 +31,8 @@ import Finish from './steps/Finish'
const STEPS = {
init: InitStep,
chooseDevice: ChooseDevice,
choosePIN: ChoosePIN,
selectDevice: SelectDevice,
selectPIN: SelectPIN,
writeSeed: WriteSeed,
genuineCheck: GenuineCheck,
setPassword: SetPassword,
@ -128,7 +128,7 @@ class Onboarding extends PureComponent<Props> {
const Container = styled(Box).attrs({
bg: 'white',
p: 5,
p: 60,
})`
position: fixed;
top: 0;
@ -138,6 +138,6 @@ const Container = styled(Box).attrs({
z-index: 25;
`
const StepContainer = styled(Box).attrs({
p: 20,
p: 40,
})``
export default compose(connect(mapStateToProps, mapDispatchToProps), translate())(Onboarding)

62
src/components/Onboarding/steps/ChooseDevice.js

@ -1,62 +0,0 @@
// @flow
import React from 'react'
import styled from 'styled-components'
import Box from 'components/base/Box'
import IconNanoS from 'icons/device/NanoS'
import IconBlue from 'icons/device/Blue'
import { Title, Description, Inner } from '../helperComponents'
import type { StepProps } from '..'
export default (props: StepProps) => {
const { nextStep } = props
return (
<Box sticky alignItems="center" justifyContent="center">
<Box align="center">
<Title>This is the title of the screen. 1 line is the maximum</Title>
<Description>
This is a long text, please replace it with the final wording once its done.
<br />
Lorem ipsum dolor amet ledger lorem dolor ipsum amet
</Description>
<Box>
<Inner>
<DeviceContainer onClick={() => nextStep()}>
<DeviceIcon>
<IconNanoS size={46} />
</DeviceIcon>
<Title>Ledger Nano S</Title>
<Description>Please replace it with the final wording once its done.</Description>
</DeviceContainer>
<DeviceContainer>
<DeviceIcon>
<IconBlue size={46} />
</DeviceIcon>
<Title>Ledger Blue</Title>
<Description>Please replace it with the final wording once its done.</Description>
</DeviceContainer>
</Inner>
</Box>
</Box>
</Box>
)
}
const DeviceContainer = styled(Box).attrs({
alignItems: 'center',
justifyContent: 'center',
})`
width: 218px;
height: 204px;
border: 1px solid #d8d8d8;
`
const DeviceIcon = styled(Box).attrs({
alignItems: 'center',
justifyContent: 'center',
color: 'graphite',
})`
width: 55px;
`

33
src/components/Onboarding/steps/ChoosePIN.js

@ -1,33 +0,0 @@
// @flow
import React from 'react'
import Box from 'components/base/Box'
import Button from 'components/base/Button'
import { Title, Description, OnboardingFooter } from '../helperComponents'
import type { StepProps } from '..'
export default (props: StepProps) => {
const { nextStep, prevStep } = props
return (
<Box sticky alignItems="center" justifyContent="center">
<Box align="center">
<Title>This is CHOOSE PIN screen. 1 line is the maximum</Title>
<Description>
This is a long text, please replace it with the final wording once its done.
<br />
Lorem ipsum dolor amet ledger lorem dolor ipsum amet
</Description>
</Box>
<OnboardingFooter horizontal align="center" justify="flex-end" flow={2}>
<Button small outline onClick={() => prevStep()}>
Go Back
</Button>
<Button small primary onClick={() => nextStep()}>
Continue
</Button>
</OnboardingFooter>
</Box>
)
}

89
src/components/Onboarding/steps/Finish.js

@ -1,34 +1,93 @@
// @flow
import React from 'react'
import { shell } from 'electron'
import styled from 'styled-components'
import Box from 'components/base/Box'
import Button from 'components/base/Button'
import Text from 'components/base/Text'
import IconFinishOnboarding from 'icons/LockScreen'
import IconCheckCircle from 'icons/CheckCircle'
import IconSocialTwitter from 'icons/Eye'
import IconSocialReddit from 'icons/User'
import IconSocialGithub from 'icons/Share'
import type { StepProps } from '..'
import { Title, Description } from '../helperComponents'
const socialMedia = [
{
key: 'twitter',
url: 'https://twitter.com/LedgerHQ',
icon: <IconSocialTwitter size={24} />,
onClick: url => shell.openExternal(url),
},
{
key: 'reddit',
url: 'https://www.reddit.com/r/ledgerwallet/',
icon: <IconSocialReddit size={24} />,
onClick: url => shell.openExternal(url),
},
{
key: 'github',
url: 'https://github.com/LedgerHQ',
icon: <IconSocialGithub size={24} />,
onClick: url => shell.openExternal(url),
},
]
export default (props: StepProps) => {
const { finish, jumpStep } = props
const { finish, t } = props
return (
<Box sticky alignItems="center" justifyContent="center">
<Box align="center">
<Title>This is ENJOY THE APP screen. 1 line is the maximum</Title>
<Description>
This is a long text, please replace it with the final wording once its done.
<br />
Lorem ipsum dolor amet ledger lorem dolor ipsum amet
</Description>
<IconFinishOnboarding size={136} />
<Button small primary onClick={() => finish()}>
Open App
<Box align="center" alignItems="center">
<Box color="positiveGreen">
<IconCheckCircle size={44} />
</Box>
<Box style={{ paddingTop: '20px', maxWidth: 536 }} align="center" mb={5}>
<Title>{t('onboarding:finish.title')}</Title>
<Description>{t('onboarding:finish.desc')}</Description>
</Box>
<Button primary onClick={() => finish()}>
{t('onboarding:finish.openAppButton')}
</Button>
<Box onClick={() => jumpStep('start')} style={{ padding: 15 }}>
<Text color="smoke">I want to go back to Onboarding</Text>
<Box alignItems="center" mt={7}>
<FollowUsDesc>{t('onboarding:finish.followUsLabel')}</FollowUsDesc>
</Box>
<Box horizontal flow={5} color="grey">
{socialMedia.map(socMed => <SocialMediaBox key={socMed.key} socMed={socMed} />)}
</Box>
</Box>
</Box>
)
}
type SocMed = {
icon: any,
url: string,
onClick: string => void,
}
export function SocialMediaBox({ socMed }: { socMed: SocMed }) {
const { icon, url, onClick } = socMed
return (
<Box
horizontal
style={{
cursor: 'pointer',
}}
onClick={() => onClick(url)}
>
{icon}
</Box>
)
}
export const FollowUsDesc = styled(Box).attrs({
ff: 'Museo Sans|Regular',
fontSize: 4,
textAlign: 'center',
color: 'grey',
})`
margin: 10px auto;
`

157
src/components/Onboarding/steps/Init.js

@ -1,90 +1,109 @@
// @flow
import React from 'react'
import styled from 'styled-components'
import { shell } from 'electron'
import Box from 'components/base/Box'
import styled from 'styled-components'
import Box, { Card } from 'components/base/Box'
import IconUser from 'icons/User'
import { Title, Description, Inner } from '../helperComponents'
import IconChevronRight from 'icons/ChevronRight'
import { Title } from '../helperComponents'
import type { StepProps } from '..'
export default (props: StepProps) => {
const { nextStep, jumpStep } = props
const handleOpenLink = (url: string) => () => shell.openExternal(url)
/* TODO: all titles, descriptions to be wrapped in a translation tag once defined */
const { nextStep, jumpStep, t } = props
const optionCards = [
{
key: 'newDevice',
icon: <IconUser size={22} />,
title: t('onboarding:init.newDevice.title'),
desc: t('onboarding:init.newDevice.desc'),
onClick: () => nextStep(),
},
{
key: 'restoreDevice',
icon: <IconUser size={22} />,
title: t('onboarding:init.restoreDevice.title'),
desc: t('onboarding:init.restoreDevice.desc'),
onClick: () => jumpStep('choosePIN'),
},
{
key: 'initializedDevice',
icon: <IconUser size={22} />,
title: t('onboarding:init.initializedDevice.title'),
desc: t('onboarding:init.initializedDevice.desc'),
onClick: () => jumpStep('choosePIN'),
},
{
key: 'noDevice',
icon: <IconUser size={22} />,
title: t('onboarding:init.noDevice.title'),
desc: t('onboarding:init.noDevice.desc'),
onClick: () => shell.openExternal('https://www.ledger.fr/'),
},
]
return (
<Box sticky alignItems="center" justifyContent="center">
<Box align="center">
<Title>This is the title of the screen. 1 line is the maximum</Title>
<Description>
This is a long text, please replace it with the final wording once its done.
<br />
Lorem ipsum dolor amet ledger lorem dolor ipsum amet
</Description>
<Box style={{ paddingBottom: 10 }}>
<Inner>
<DeviceContainer onClick={() => nextStep()}>
{/* colors are temp, we don't have icons now */}
<DeviceIcon style={{ color: '#66be54' }}>
<IconUser size={24} />
</DeviceIcon>
<TrackChoiceTitle>Clean Nano S setup</TrackChoiceTitle>
<Description>Please replace it with the final wording once its done.</Description>
</DeviceContainer>
<DeviceContainer onClick={() => jumpStep('choosePIN')}>
<DeviceIcon style={{ color: '#66be54' }}>
<IconUser size={24} />
</DeviceIcon>
<TrackChoiceTitle>Existing seed + Clean setup</TrackChoiceTitle>
<Description>Please replace it with the final wording once its done.</Description>
</DeviceContainer>
</Inner>
<Box color="wallet">
<IconUser size={36} />
</Box>
<Box style={{ padding: 20, maxWidth: 650 }}>
<Title>{t('onboarding:init.title')}</Title>
</Box>
<Box>
<Inner>
<DeviceContainer onClick={() => nextStep()}>
<DeviceIcon style={{ color: '#6490f1' }}>
<IconUser size={24} />
</DeviceIcon>
<TrackChoiceTitle>Migrate accounts</TrackChoiceTitle>
<Description>Please replace it with the final wording once its done.</Description>
</DeviceContainer>
<DeviceContainer onClick={handleOpenLink('https://www.ledger.fr/')}>
<DeviceIcon style={{ color: '#ea2e41' }}>
<IconUser size={24} />
</DeviceIcon>
<TrackChoiceTitle>Not a user, but would love to</TrackChoiceTitle>
<Description>Please replace it with the final wording once its done.</Description>
</DeviceContainer>
</Inner>
<Box mt={5} flow={5}>
{optionCards.map(card => <OptionFlowCard key={card.key} card={card} />)}
</Box>
</Box>
</Box>
)
}
const DeviceContainer = styled(Box).attrs({
alignItems: 'center',
justifyContent: 'center',
})`
width: 218px;
height: 204px;
border: 1px solid #d8d8d8;
`
const DeviceIcon = styled(Box).attrs({
alignItems: 'center',
justifyContent: 'center',
color: 'graphite',
})`
width: 55px;
padding: 10px;
`
export const TrackChoiceTitle = styled(Box).attrs({
width: 152,
height: 27,
ff: 'Museo Sans|Regular',
fontSize: 5,
color: 'dark',
type CardType = {
icon: any,
desc: any,
title: any,
onClick: Function,
}
export function OptionFlowCard({ card }: { card: CardType }) {
const { icon, desc, title, onClick } = card
return (
<Card
horizontal
p={5}
style={{
cursor: 'pointer',
border: 'solid 1px #d8d8d8',
minWidth: '533px',
maxHeight: '80px',
}}
onClick={onClick}
>
<Box justify="center" color="grey" style={{ width: 50 }}>
{icon}
</Box>
<Box ff="Open Sans|Regular" justify="center" fontSize={4} grow>
<CardTitle>{title}</CardTitle>
<CardDescription>{desc}</CardDescription>
</Box>
<Box justify="center" color="grey">
<IconChevronRight size={22} />
</Box>
</Card>
)
}
export const CardDescription = styled(Box).attrs({
ff: 'Open Sans|Regular',
fontSize: 4,
textAlign: 'left',
color: 'grey',
})``
export const CardTitle = styled(Box).attrs({
ff: 'Open Sans|SemiBold',
fontSize: 4,
textAlign: 'left',
})``

79
src/components/Onboarding/steps/SelectDevice.js

@ -0,0 +1,79 @@
// @flow
import React from 'react'
import styled from 'styled-components'
import Box from 'components/base/Box'
import IconLedgerNano from 'icons/onboarding/LedgerNano'
import IconLedgerBlue from 'icons/onboarding/LedgerBlue'
import { Title, Description, Inner } from '../helperComponents'
import type { StepProps } from '..'
export default (props: StepProps) => {
const { nextStep, t } = props
return (
<Box sticky alignItems="center" justifyContent="center">
<Box align="center">
<Title>{t('onboarding:selectDevice.title')}</Title>
<Description style={{ maxWidth: 714 }}>{t('onboarding:selectDevice.desc')}</Description>
<Box>
<Inner>
<DeviceContainer onClick={() => nextStep()}>
<DeviceIcon>
<IconLedgerNano />
</DeviceIcon>
<BlockTitle pb={3}>{t('onboarding:selectDevice.ledgerNanoCard.title')}</BlockTitle>
<BlockDescription>
{t('onboarding:selectDevice.ledgerNanoCard.desc')}
</BlockDescription>
</DeviceContainer>
<DeviceContainer>
<DeviceIcon>
<IconLedgerBlue />
</DeviceIcon>
<BlockTitle pb={3}>{t('onboarding:selectDevice.ledgerBlueCard.title')}</BlockTitle>
<BlockDescription>
{t('onboarding:selectDevice.ledgerBlueCard.desc')}
</BlockDescription>
</DeviceContainer>
</Inner>
</Box>
</Box>
</Box>
)
}
const DeviceContainer = styled(Box).attrs({
alignItems: 'center',
justifyContent: 'center',
})`
width: 218px;
height: 204px;
border: 1px solid #d8d8d8;
&:hover,
&:focus {
opacity: 0.5;
cursor: pointer;
}
`
const DeviceIcon = styled(Box).attrs({
alignItems: 'center',
justifyContent: 'center',
color: 'graphite',
})`
width: 55px;
min-height: 80px;
`
export const BlockDescription = styled(Box).attrs({
ff: 'Open Sans|Regular',
fontSize: 4,
textAlign: 'center',
color: 'grey',
})``
export const BlockTitle = styled(Box).attrs({
ff: 'Open Sans|SemiBold',
fontSize: 4,
textAlign: 'center',
})``

72
src/components/Onboarding/steps/SelectPIN.js

@ -0,0 +1,72 @@
// @flow
import React from 'react'
import Box from 'components/base/Box'
import IconSelectPIN from 'icons/onboarding/SelectPIN'
import {
Title,
Description,
Inner,
InstructionStep,
IconInstructionStep,
} from '../helperComponents'
import OnboardingFooter from '../OnboardingFooter'
import type { StepProps } from '..'
export default (props: StepProps) => {
const { nextStep, prevStep, t } = props
const steps = [
{
key: 'step1',
icon: <IconInstructionStep>1</IconInstructionStep>,
desc: t('onboarding:selectPIN.instructions.step1'),
},
{
key: 'step2',
icon: <IconInstructionStep>2</IconInstructionStep>,
desc: t('onboarding:selectPIN.instructions.step2'),
},
{
key: 'step3',
icon: <IconInstructionStep>3</IconInstructionStep>,
desc: t('onboarding:selectPIN.instructions.step3'),
},
{
key: 'step4',
icon: <IconInstructionStep>4</IconInstructionStep>,
desc: t('onboarding:selectPIN.instructions.step4'),
},
]
return (
<Box sticky>
<Box grow alignItems="center" justifyContent="center">
<Box align="center" mb={5}>
<Title>{t('onboarding:selectPIN.title')}</Title>
<Description style={{ maxWidth: 714 }}>{t('onboarding:selectPIN.desc')}</Description>
</Box>
<Box>
<Inner style={{ width: 760 }}>
<Box style={{ width: 260 }} mt={5}>
<IconSelectPIN />
</Box>
<Box shrink grow flow={5}>
{steps.map(step => <InstructionStep key={step.key} step={step} />)}
</Box>
</Inner>
</Box>
</Box>
<OnboardingFooter
horizontal
align="center"
flow={2}
t={t}
nextStep={nextStep}
prevStep={prevStep}
/>
</Box>
)
}

15
src/components/Onboarding/steps/Start.js

@ -5,20 +5,21 @@ import React from 'react'
import Box from 'components/base/Box'
import Button from 'components/base/Button'
import LedgerLogo from 'icons/LockScreen'
import IconGetStarted from 'icons/onboarding/GetStartedLogo'
import type { StepProps } from '..'
import { Title, Description } from '../helperComponents'
export default (props: StepProps) => {
const { jumpStep } = props
const { jumpStep, t } = props
return (
<Box sticky alignItems="center" justifyContent="center">
<Box align="center" alignItems="center">
<LedgerLogo size={136} />
<Title>Ledger Live</Title>
<Title>Welcome to the new Ledger Live Desktop app.</Title>
<Description>Lets get started!</Description>
<Button small primary onClick={() => jumpStep('init')}>
<IconGetStarted />
<Box style={{ paddingTop: '20px' }}>
<Title>{t('onboarding:start.title')}</Title>
<Description>{t('onboarding:start.desc')}</Description>
</Box>
<Button primary onClick={() => jumpStep('init')}>
Get Started
</Button>
</Box>

81
src/components/Onboarding/steps/WriteSeed.js

@ -3,31 +3,74 @@
import React from 'react'
import Box from 'components/base/Box'
import Button from 'components/base/Button'
import { Title, Description, OnboardingFooter } from '../helperComponents'
import IconWriteSeed from 'icons/onboarding/WriteSeed'
import {
Title,
Description,
Inner,
InstructionStep,
IconInstructionStep,
} from '../helperComponents'
import OnboardingFooter from '../OnboardingFooter'
import type { StepProps } from '..'
export default (props: StepProps) => {
const { nextStep, prevStep } = props
const { nextStep, prevStep, t } = props
const steps = [
{
key: 'step1',
icon: <IconInstructionStep>1</IconInstructionStep>,
desc: t('onboarding:writeSeed.instructions.step1'),
},
{
key: 'step2',
icon: <IconInstructionStep>2</IconInstructionStep>,
desc: t('onboarding:writeSeed.instructions.step2'),
},
{
key: 'step3',
icon: <IconInstructionStep>3</IconInstructionStep>,
desc: t('onboarding:writeSeed.instructions.step3'),
},
{
key: 'step4',
icon: <IconInstructionStep>4</IconInstructionStep>,
desc: t('onboarding:writeSeed.instructions.step4'),
},
{
key: 'step5',
icon: <IconInstructionStep>5</IconInstructionStep>,
desc: t('onboarding:writeSeed.instructions.step5'),
},
]
return (
<Box sticky alignItems="center" justifyContent="center">
<Box align="center">
<Title>This is WRITE SEED screen. 1 line is the maximum</Title>
<Description>
This is a long text, please replace it with the final wording once its done.
<br />
Lorem ipsum dolor amet ledger lorem dolor ipsum amet
</Description>
<Box sticky>
<Box grow alignItems="center" justifyContent="center">
<Box align="center" mb={5}>
<Title>{t('onboarding:writeSeed.title')}</Title>
<Description style={{ maxWidth: 714 }}>{t('onboarding:writeSeed.desc')}</Description>
</Box>
<Box>
<Inner style={{ width: 760 }}>
<Box style={{ width: 260, alignItems: 'center' }} mt={4}>
<IconWriteSeed />
</Box>
<Box shrink grow flow={5}>
{steps.map(step => <InstructionStep key={step.key} step={step} />)}
</Box>
</Inner>
</Box>
</Box>
<OnboardingFooter horizontal align="center" justify="flex-end" flow={2}>
<Button small outline onClick={() => prevStep()}>
Go Back
</Button>
<Button small primary onClick={() => nextStep()}>
Continue
</Button>
</OnboardingFooter>
<OnboardingFooter
horizontal
align="center"
flow={2}
t={t}
nextStep={nextStep}
prevStep={prevStep}
/>
</Box>
)
}

20
src/components/TopBar.js

@ -11,7 +11,7 @@ import { ipcRenderer } from 'electron'
import type { Location, RouterHistory } from 'react-router'
import type { T } from 'types/common'
import { rgba } from 'styles/helpers'
import { rgba, darken } from 'styles/helpers'
import { lock } from 'reducers/application'
import { hasPassword } from 'reducers/settings'
@ -50,6 +50,18 @@ const Bar = styled.div`
background: ${p => p.theme.colors.fog};
`
const SettingButtonContainer = styled(Box).attrs({
px: 4,
ml: 0,
justifyContent: 'center',
cursor: 'pointer',
})`
&:hover > * {
color: ${p => darken(p.theme.colors.graphite, 0.15)};
cursor: pointer;
}
`
const Activity = styled.div`
background: ${p =>
p.progress === true
@ -152,7 +164,7 @@ class TopBar extends PureComponent<Props, State> {
<Container bg="lightGrey" color="graphite">
<Inner>
<Box grow horizontal flow={4}>
<GlobalSearch t={t} />
<GlobalSearch t={t} isHidden />
<Box justifyContent="center">
<IconDevices size={16} />
</Box>
@ -175,9 +187,9 @@ class TopBar extends PureComponent<Props, State> {
<Box justifyContent="center">
<Bar />
</Box>
<Box justifyContent="center" onClick={this.navigateToSettings}>
<SettingButtonContainer onClick={this.navigateToSettings}>
<IconSettings size={16} />
</Box>
</SettingButtonContainer>
{hasPassword && (
<Fragment>
<Box justifyContent="center">

6
src/components/base/Box/index.js

@ -12,7 +12,6 @@ import {
justifyContent,
space,
style,
cursor,
} from 'styled-system'
import fontFamily from 'styles/styled/fontFamily'
@ -24,6 +23,11 @@ const textAlign = style({
cssProperty: 'textAlign',
})
const cursor = style({
prop: 'cursor',
cssProperty: 'cursor',
})
const Box = styled.div`
${alignItems};
${borderRadius};

32
src/components/modals/SettingsAccount.js

@ -4,7 +4,7 @@ import React, { PureComponent } from 'react'
import { connect } from 'react-redux'
import get from 'lodash/get'
import { push } from 'react-router-redux'
import type { Account } from '@ledgerhq/live-common/lib/types'
import type { Account, Unit } from '@ledgerhq/live-common/lib/types'
import { MODAL_SETTINGS_ACCOUNT } from 'config/constants'
@ -14,6 +14,7 @@ import { setDataModal, closeModal } from 'reducers/modals'
import Box from 'components/base/Box'
import Button from 'components/base/Button'
import Input from 'components/base/Input'
import Select from 'components/base/Select/index'
import Modal, { ModalBody, ModalTitle, ModalFooter, ModalContent } from 'components/base/Modal'
import Label from 'components/base/Label'
@ -24,6 +25,7 @@ type State = {
minConfirmations: number | null,
editName: boolean,
nameHovered: boolean,
editUnit: boolean,
}
type Props = {
@ -47,6 +49,7 @@ const defaultState = {
accountName: null,
minConfirmations: null,
nameHovered: false,
editUnit: false,
}
function hasNoOperations(account: Account) {
@ -62,7 +65,6 @@ class SettingsAccount extends PureComponent<Props, State> {
const { accountName, minConfirmations } = this.state
const account = get(data, 'account', {})
return {
...account,
...(accountName !== null
@ -146,8 +148,15 @@ class SettingsAccount extends PureComponent<Props, State> {
...defaultState,
})
handleChangeUnit = (value: Unit, account: Account) => {
const { updateAccount, setDataModal } = this.props
account = { ...account, unit: value }
updateAccount(account)
setDataModal(MODAL_SETTINGS_ACCOUNT, { account })
}
render() {
const { editName, nameHovered } = this.state
const { editName, nameHovered, editUnit } = this.state
return (
<Modal
@ -155,7 +164,6 @@ class SettingsAccount extends PureComponent<Props, State> {
onHide={this.handleHide}
render={({ data, onClose }) => {
const account = this.getAccount(data)
return (
<ModalBody onClose={onClose}>
<ModalTitle>{'Account settings'}</ModalTitle>
@ -205,12 +213,26 @@ class SettingsAccount extends PureComponent<Props, State> {
onChange={this.handleChangeMinConfirmations(account)}
/>
</Box>
{editUnit && (
<Box>
<Label>{'Edit Units'}</Label>
<Select
keyProp="code"
onChange={value => this.handleChangeUnit(value, account)}
renderSelected={item => item && item.code}
value={account.unit}
items={account.currency.units}
/>
</Box>
)}
</ModalContent>
<ModalFooter horizontal justify="flex-end" flow={2}>
<Button onClick={this.handleArchiveAccount(account)}>
{hasNoOperations(account) ? 'Remove account' : 'Archive account'}
</Button>
<Button primary>Go to account</Button>
<Button primary onClick={onClose}>
Go to account
</Button>
</ModalFooter>
</ModalBody>
)

79
src/icons/onboarding/GetStartedLogo.js

@ -0,0 +1,79 @@
// @flow
import React from 'react'
export default () => (
<svg width="113" height="109">
<g fill="none" fillRule="evenodd">
<rect
width="1.44"
height="5.6"
y="16.6"
fill="#1D2028"
rx=".72"
transform="matrix(-1 0 0 1 1.44 0)"
/>
<rect
width="1.44"
height="5.6"
y="34.8"
fill="#1D2028"
rx=".72"
transform="matrix(-1 0 0 1 1.44 0)"
/>
<path
fill="#6490F1"
fillOpacity=".1"
stroke="#1D2028"
strokeWidth="2"
d="M16.592 12c.225 0 .408.183.408.408v95.184a.408.408 0 0 1-.408.408H2.128a.408.408 0 0 1-.408-.408V12.408c0-.225.183-.408.408-.408h14.464z"
/>
<rect
width="7.64"
height="27"
x="5.513"
y="18.522"
fill="#FFF"
stroke="#6490F1"
rx=".704"
transform="matrix(-1 0 0 1 18.665 0)"
/>
<path
fill="#FFF"
stroke="#1D2028"
strokeWidth="2"
d="M9.36 54A7.64 7.64 0 0 1 17 61.64v45.952a.408.408 0 0 1-.408.408H2.128a.408.408 0 0 1-.408-.408V61.64A7.64 7.64 0 0 1 9.36 54z"
/>
<ellipse
cx="9.36"
cy="61.4"
fill="#FFF"
stroke="#6490F1"
rx="3.82"
ry="3.7"
transform="matrix(-1 0 0 1 18.72 0)"
/>
<rect width="3.137" height="9.306" x="109.863" y="13.959" fill="#1D2028" rx="1.569" />
<rect
width="76.431"
height="106.571"
x="34"
y="1"
fill="#6490F1"
fillOpacity=".1"
stroke="#1D2027"
strokeWidth="2"
rx="5.44"
/>
<rect
width="52.333"
height="79.653"
x="46.043"
y="15.235"
fill="#FFF"
stroke="#6490F1"
rx="4.08"
/>
</g>
</svg>
)

32
src/icons/onboarding/LedgerBlue.js

@ -0,0 +1,32 @@
// @flow
import React from 'react'
export default () => (
<svg width="41" height="56">
<g fill="none" fillRule="evenodd">
<rect width="1.608" height="4.8" x="39.392" y="7.2" fill="#1D2028" rx=".804" />
<rect
width="38.696"
height="54.5"
x=".75"
y=".75"
fill="#6490F1"
fillOpacity=".1"
stroke="#1D2027"
strokeWidth="1.5"
rx="3.2"
/>
<rect
width="26.833"
height="41.1"
x="6.678"
y="7.85"
fill="#FFF"
stroke="#6490F1"
strokeWidth=".5"
rx="2.4"
/>
</g>
</svg>
)

36
src/icons/onboarding/LedgerNano.js

@ -0,0 +1,36 @@
// @flow
import React from 'react'
export default () => (
<svg width="112" height="20">
<g fill="none" fillRule="evenodd" transform="rotate(-90 10 10)">
<rect width="1.6" height="6.4" x="18.4" y="6.4" fill="#1D2028" rx=".8" />
<rect width="1.6" height="6.4" x="18.4" y="27.2" fill="#1D2028" rx=".8" />
<path
fill="#6490F1"
fillOpacity=".1"
stroke="#1D2028"
strokeWidth="1.5"
d="M1.6.75a.85.85 0 0 0-.85.85v108.8c0 .47.38.85.85.85h16c.47 0 .85-.38.85-.85V1.6a.85.85 0 0 0-.85-.85h-16z"
/>
<rect
width="9.1"
height="31.5"
x="5.081"
y="8.275"
fill="#FFF"
stroke="#6490F1"
strokeWidth=".5"
rx=".8"
/>
<path
fill="#FFF"
stroke="#1D2028"
strokeWidth="1.5"
d="M9.6 48.75A8.85 8.85 0 0 0 .75 57.6v52.8c0 .47.38.85.85.85h16c.47 0 .85-.38.85-.85V57.6a8.85 8.85 0 0 0-8.85-8.85z"
/>
<circle cx="9.6" cy="57.6" r="4.55" fill="#FFF" stroke="#6490F1" strokeWidth=".5" />
</g>
</svg>
)

75
src/icons/onboarding/SelectPIN.js

@ -0,0 +1,75 @@
// @flow
import React from 'react'
export default () => (
<svg width="260" height="129">
<defs>
<linearGradient id="a" x1="50%" x2="50%" y1="100%" y2="0%">
<stop offset="1.367%" stopColor="#FFF" />
<stop offset="100%" stopColor="#1D2027" />
</linearGradient>
<path
id="b"
d="M91 0h33.711a4 4 0 0 1 4 4v108.144c0 11.519-9.337 20.856-20.855 20.856C96.337 133 87 123.663 87 112.144V4a4 4 0 0 1 4-4z"
/>
</defs>
<g fill="none" fillRule="evenodd">
<path
stroke="#1D2027"
strokeWidth="2"
d="M126.962 31.06a1 1 0 0 1-1 1H99.737a5 5 0 0 1-5-5v-8.485a5 5 0 0 1 5-5h26.225a1 1 0 0 1 1 1V31.06zm-32.608-5.208h-10.93v-6.435h10.93v6.435z"
/>
<path
stroke="#1D2027"
d="M127.53 28.836V16.58h11.076a1.5 1.5 0 0 1 1.5 1.5v9.256a1.5 1.5 0 0 1-1.5 1.5H127.53z"
/>
<path
d="M138.202 19.495h-6.794m6.794 6.208h-6.794"
stroke="#1D2027"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
stroke="url(#a)"
strokeWidth="2.772"
d="M8.222 59.31h.23l-.23-.23v-1.155l-.578.577-.578-.577v1.155l-.23.23h.23v79.88h-.23l.23.23v1.156l.578-.578.578.578v-1.156l.23-.23h-.23V59.31zm5.657 0h.23l-.23-.23v-1.155l-.578.577-.578-.577v1.155l-.23.23h.23v79.88h-.23l.23.23v1.156l.578-.578.578.578v-1.156l.23-.23h-.23V59.31z"
transform="matrix(0 -1 -1 0 140.606 33.06)"
/>
<g transform="rotate(-90 128.59 1.975)">
<rect width="4.492" height="17.12" x="125.336" y="15.505" fill="#142533" rx="2" />
<rect width="4.492" height="17.12" x="125.336" y="70.094" fill="#142533" rx="2" />
<use fill="#FFF" xlinkHref="#b" />
<path
fill="#6490F1"
fillOpacity=".15"
stroke="#142533"
strokeLinejoin="square"
strokeWidth="2"
d="M91 1a3 3 0 0 0-3 3v108.144C88 123.11 96.89 132 107.856 132c10.966 0 19.855-8.89 19.855-19.856V4a3 3 0 0 0-3-3H91z"
/>
<rect
width="20.176"
height="61.019"
x="97.5"
y="21.5"
fill="#FFF"
stroke="#6490F1"
rx="1.6"
/>
<path
fill="#6490F1"
fillRule="nonzero"
d="M103.735 40.983v21.563c0 .397.225.719.502.719h6.526c.277 0 .502-.322.502-.719V40.983c0-.396-.225-.718-.502-.718h-6.526c-.277 0-.502.322-.502.718zm3.976 16.332c.04 0 .073.032.073.072v.73c0 .03.018.057.046.069a.08.08 0 0 0 .082-.016l.517-.515a.073.073 0 0 1 .105 0l.299.295a.077.077 0 0 1 0 .105l-.517.515a.075.075 0 0 0 .052.127h.73c.042 0 .076.034.076.075v.418a.075.075 0 0 1-.075.075h-.73a.075.075 0 1 0-.053.127l.517.515a.077.077 0 0 1 0 .105l-.299.295a.073.073 0 0 1-.105 0l-.517-.515a.076.076 0 0 0-.128.053v.727a.072.072 0 0 1-.073.075h-.422a.073.073 0 0 1-.073-.075v-.727a.076.076 0 0 0-.128-.052l-.517.514a.073.073 0 0 1-.105 0l-.299-.292a.077.077 0 0 1 0-.105l.517-.515a.075.075 0 0 0-.052-.128h-.73a.075.075 0 0 1-.076-.075v-.427c0-.042.034-.075.075-.075h.73c.03 0 .058-.019.07-.047a.075.075 0 0 0-.017-.08l-.517-.516a.077.077 0 0 1 0-.105l.299-.295a.073.073 0 0 1 .105 0l.517.515a.076.076 0 0 0 .128-.052v-.73c0-.04.033-.073.073-.073l.422.008zm0-4.718c.04.002.073.035.073.075v.728c0 .03.018.057.046.068.028.011.06.005.082-.016l.517-.515a.078.078 0 0 1 .105 0l.299.298a.077.077 0 0 1 0 .105l-.517.515a.075.075 0 0 0 .052.127h.73c.041 0 .075.032.076.073v.42a.075.075 0 0 1-.075.072h-.73a.075.075 0 1 0-.053.127l.517.516a.077.077 0 0 1 0 .105l-.299.297a.078.078 0 0 1-.105 0l-.517-.515a.076.076 0 0 0-.128.053v.727c0 .04-.033.074-.073.075h-.422a.075.075 0 0 1-.073-.075v-.727a.076.076 0 0 0-.128-.052l-.517.514a.078.078 0 0 1-.105 0l-.299-.297a.077.077 0 0 1 0-.105l.517-.515a.075.075 0 0 0-.052-.128h-.73a.075.075 0 0 1-.076-.072v-.42a.075.075 0 0 1 .075-.073h.73c.03 0 .058-.018.07-.046a.075.075 0 0 0-.017-.081l-.517-.515a.077.077 0 0 1 0-.105l.299-.298a.078.078 0 0 1 .105 0l.517.515a.076.076 0 0 0 .128-.052v-.728c0-.04.033-.073.073-.075h.422zm0-4.715a.073.073 0 0 1 .073.075v.728c0 .03.018.057.046.068.028.011.06.005.082-.016l.517-.515a.073.073 0 0 1 .105 0l.299.293a.077.077 0 0 1 0 .105l-.517.515a.075.075 0 0 0 .052.127h.73c.042 0 .076.034.076.075v.428a.075.075 0 0 1-.075.075h-.73a.075.075 0 1 0-.053.127l.517.515a.077.077 0 0 1 0 .105l-.299.295a.073.073 0 0 1-.105 0l-.517-.515a.076.076 0 0 0-.128.053v.722c0 .04-.033.073-.073.073h-.422a.073.073 0 0 1-.073-.073v-.73a.076.076 0 0 0-.128-.052l-.517.515a.073.073 0 0 1-.105 0l-.299-.295a.077.077 0 0 1 0-.105l.517-.515a.075.075 0 0 0-.052-.128h-.73a.075.075 0 0 1-.076-.075v-.417c0-.042.034-.075.075-.075h.73c.03 0 .058-.019.07-.047a.075.075 0 0 0-.017-.08l-.517-.516a.077.077 0 0 1 0-.105l.299-.295a.073.073 0 0 1 .105 0l.517.515a.076.076 0 0 0 .128-.052v-.728a.072.072 0 0 1 .073-.075h.422zm0-5a.073.073 0 0 1 .073.075v.728c0 .03.018.057.046.068.028.011.06.005.082-.016l.517-.515a.073.073 0 0 1 .105 0l.299.293a.077.077 0 0 1 0 .105l-.517.515a.075.075 0 0 0 .052.127h.73c.042 0 .076.034.076.075v.428a.075.075 0 0 1-.075.075h-.73a.075.075 0 1 0-.053.127l.517.515a.077.077 0 0 1 0 .105l-.299.295a.073.073 0 0 1-.105 0l-.517-.515a.076.076 0 0 0-.128.053v.722c0 .04-.033.073-.073.073h-.422a.073.073 0 0 1-.073-.073v-.73a.076.076 0 0 0-.128-.052l-.517.515a.073.073 0 0 1-.105 0l-.299-.295a.077.077 0 0 1 0-.105l.517-.515a.075.075 0 0 0-.052-.128h-.73a.075.075 0 0 1-.076-.075v-.417c0-.042.034-.075.075-.075h.73c.03 0 .058-.019.07-.047a.075.075 0 0 0-.017-.08l-.517-.516a.077.077 0 0 1 0-.105l.299-.295a.073.073 0 0 1 .105 0l.517.515a.076.076 0 0 0 .128-.052v-.728a.072.072 0 0 1 .073-.075h.422z"
/>
<path
fill="#FFF"
stroke="#142533"
strokeWidth="2"
d="M123.166 125.105c7.049-8.4 5.953-20.925-2.447-27.974l-90.824-76.21a3 3 0 0 0-4.227.37L4 47.115a3 3 0 0 0 .37 4.227l90.824 76.21c8.4 7.049 20.924 5.953 27.973-2.447z"
/>
<ellipse cx="108.016" cy="111.123" stroke="#6490F1" rx="10.57" ry="10.644" />
</g>
</g>
</svg>
)

197
src/icons/onboarding/WriteSeed.js

@ -0,0 +1,197 @@
// @flow
import React from 'react'
export default () => (
<svg width="157" height="144">
<defs>
<rect id="b" width="42" height="10" y="45" rx="2" />
<filter
id="a"
width="123.8%"
height="200%"
x="-11.9%"
y="-40%"
filterUnits="objectBoundingBox"
>
<feOffset dy="1" in="SourceAlpha" result="shadowOffsetOuter1" />
<feGaussianBlur in="shadowOffsetOuter1" result="shadowBlurOuter1" stdDeviation="1.5" />
<feColorMatrix
in="shadowBlurOuter1"
values="0 0 0 0 0.847058824 0 0 0 0 0.847058824 0 0 0 0 0.847058824 0 0 0 1 0"
/>
</filter>
<rect id="d" width="42" height="10" x="67" y="35" rx="2" />
<filter
id="c"
width="123.8%"
height="200%"
x="-11.9%"
y="-40%"
filterUnits="objectBoundingBox"
>
<feOffset dy="1" in="SourceAlpha" result="shadowOffsetOuter1" />
<feGaussianBlur in="shadowOffsetOuter1" result="shadowBlurOuter1" stdDeviation="1.5" />
<feColorMatrix
in="shadowBlurOuter1"
values="0 0 0 0 0.847058824 0 0 0 0 0.847058824 0 0 0 0 0.847058824 0 0 0 1 0"
/>
</filter>
<rect id="f" width="42" height="10" x="31" y="11" rx="2" />
<filter
id="e"
width="123.8%"
height="200%"
x="-11.9%"
y="-40%"
filterUnits="objectBoundingBox"
>
<feOffset dy="1" in="SourceAlpha" result="shadowOffsetOuter1" />
<feGaussianBlur in="shadowOffsetOuter1" result="shadowBlurOuter1" stdDeviation="1.5" />
<feColorMatrix
in="shadowBlurOuter1"
values="0 0 0 0 0.847058824 0 0 0 0 0.847058824 0 0 0 0 0.847058824 0 0 0 1 0"
/>
</filter>
<rect id="h" width="42" height="10" x="103" rx="2" />
<filter
id="g"
width="123.8%"
height="200%"
x="-11.9%"
y="-40%"
filterUnits="objectBoundingBox"
>
<feOffset dy="1" in="SourceAlpha" result="shadowOffsetOuter1" />
<feGaussianBlur in="shadowOffsetOuter1" result="shadowBlurOuter1" stdDeviation="1.5" />
<feColorMatrix
in="shadowBlurOuter1"
values="0 0 0 0 0.847058824 0 0 0 0 0.847058824 0 0 0 0 0.847058824 0 0 0 1 0"
/>
</filter>
<rect id="j" width="42" height="10" x="104" y="55" rx="2" />
<filter
id="i"
width="123.8%"
height="200%"
x="-11.9%"
y="-40%"
filterUnits="objectBoundingBox"
>
<feOffset dy="1" in="SourceAlpha" result="shadowOffsetOuter1" />
<feGaussianBlur in="shadowOffsetOuter1" result="shadowBlurOuter1" stdDeviation="1.5" />
<feColorMatrix
in="shadowBlurOuter1"
values="0 0 0 0 0.847058824 0 0 0 0 0.847058824 0 0 0 0 0.847058824 0 0 0 1 0"
/>
</filter>
<rect id="l" width="42" height="10" x="31" y="67" rx="2" />
<filter
id="k"
width="123.8%"
height="200%"
x="-11.9%"
y="-40%"
filterUnits="objectBoundingBox"
>
<feOffset dy="1" in="SourceAlpha" result="shadowOffsetOuter1" />
<feGaussianBlur in="shadowOffsetOuter1" result="shadowBlurOuter1" stdDeviation="1.5" />
<feColorMatrix
in="shadowBlurOuter1"
values="0 0 0 0 0.847058824 0 0 0 0 0.847058824 0 0 0 0 0.847058824 0 0 0 1 0"
/>
</filter>
<rect id="n" width="42" height="10" x="11" y="96" rx="2" />
<filter
id="m"
width="123.8%"
height="200%"
x="-11.9%"
y="-40%"
filterUnits="objectBoundingBox"
>
<feOffset dy="1" in="SourceAlpha" result="shadowOffsetOuter1" />
<feGaussianBlur in="shadowOffsetOuter1" result="shadowBlurOuter1" stdDeviation="1.5" />
<feColorMatrix
in="shadowBlurOuter1"
values="0 0 0 0 0.847058824 0 0 0 0 0.847058824 0 0 0 0 0.847058824 0 0 0 1 0"
/>
</filter>
<rect id="p" width="42" height="10" x="109" y="103" rx="2" />
<filter
id="o"
width="123.8%"
height="200%"
x="-11.9%"
y="-40%"
filterUnits="objectBoundingBox"
>
<feOffset dy="1" in="SourceAlpha" result="shadowOffsetOuter1" />
<feGaussianBlur in="shadowOffsetOuter1" result="shadowBlurOuter1" stdDeviation="1.5" />
<feColorMatrix
in="shadowBlurOuter1"
values="0 0 0 0 0.847058824 0 0 0 0 0.847058824 0 0 0 0 0.847058824 0 0 0 1 0"
/>
</filter>
<rect id="r" width="42" height="10" x="78" y="83" rx="2" />
<filter
id="q"
width="123.8%"
height="200%"
x="-11.9%"
y="-40%"
filterUnits="objectBoundingBox"
>
<feOffset dy="1" in="SourceAlpha" result="shadowOffsetOuter1" />
<feGaussianBlur in="shadowOffsetOuter1" result="shadowBlurOuter1" stdDeviation="1.5" />
<feColorMatrix
in="shadowBlurOuter1"
values="0 0 0 0 0.847058824 0 0 0 0 0.847058824 0 0 0 0 0.847058824 0 0 0 1 0"
/>
</filter>
</defs>
<g fill="none" fillRule="evenodd" transform="translate(3 2)">
<circle
cx="79"
cy="72"
r="57"
fill="#6490F1"
fillOpacity=".1"
stroke="#142533"
strokeWidth="2"
/>
<path
fill="#6490F1"
fillRule="nonzero"
stroke="#142533"
d="M88.63 118.285h-1.07v-6.596c0-4.791-3.846-8.689-8.574-8.689s-8.574 3.898-8.574 8.69v6.595H69.34c-1.844 0-3.339 1.515-3.339 3.384v15.695c0 1.869 1.495 3.384 3.339 3.384h19.292c1.843 0 3.339-1.515 3.339-3.384V121.67c0-1.87-1.495-3.384-3.34-3.384zm-15.22-6.596c0-3.115 2.502-5.649 5.576-5.649 3.072 0 5.573 2.534 5.573 5.65v6.595H73.41v-6.596z"
/>
<path
fill="#FFF"
d="M80.694 129.345v4.225a1.72 1.72 0 0 1-1.709 1.73 1.72 1.72 0 0 1-1.708-1.73v-4.225a3.08 3.08 0 0 1-1.325-2.54c0-1.698 1.358-3.074 3.033-3.074 1.675 0 3.033 1.377 3.033 3.075a3.083 3.083 0 0 1-1.325 2.54z"
/>
<use fill="#000" filter="url(#a)" xlinkHref="#b" />
<use fill="#FFF" xlinkHref="#b" />
<use fill="#000" filter="url(#c)" xlinkHref="#d" />
<use fill="#FFF" xlinkHref="#d" />
<use fill="#000" filter="url(#e)" xlinkHref="#f" />
<use fill="#FFF" xlinkHref="#f" />
<use fill="#000" filter="url(#g)" xlinkHref="#h" />
<use fill="#FFF" xlinkHref="#h" />
<use fill="#000" filter="url(#i)" xlinkHref="#j" />
<use fill="#FFF" xlinkHref="#j" />
<use fill="#000" filter="url(#k)" xlinkHref="#l" />
<use fill="#FFF" xlinkHref="#l" />
<use fill="#000" filter="url(#m)" xlinkHref="#n" />
<use fill="#FFF" xlinkHref="#n" />
<g>
<use fill="#000" filter="url(#o)" xlinkHref="#p" />
<use fill="#FFF" xlinkHref="#p" />
</g>
<g>
<use fill="#000" filter="url(#q)" xlinkHref="#r" />
<use fill="#FFF" xlinkHref="#r" />
</g>
</g>
</svg>
)

16
src/reducers/onboarding.js

@ -42,8 +42,8 @@ const state: OnboardingState = {
},
},
{
name: 'chooseDevice',
label: 'chooseDevice:translated',
name: 'selectDevice',
label: 'Select Device',
options: {
showFooter: false,
showBackground: true,
@ -51,8 +51,8 @@ const state: OnboardingState = {
},
},
{
name: 'choosePIN',
label: 'choosePIN:translated',
name: 'selectPIN',
label: 'Select PIN',
options: {
showFooter: false,
showBackground: true,
@ -61,7 +61,7 @@ const state: OnboardingState = {
},
{
name: 'writeSeed',
label: 'writeSeed:translated',
label: 'Write Seed',
options: {
showFooter: false,
showBackground: true,
@ -70,7 +70,7 @@ const state: OnboardingState = {
},
{
name: 'genuineCheck',
label: 'genuineCheck:translated',
label: 'Genuine Check',
options: {
showFooter: false,
showBackground: true,
@ -79,7 +79,7 @@ const state: OnboardingState = {
},
{
name: 'setPassword',
label: 'Password:translated',
label: 'Set Password',
options: {
showFooter: false,
showBackground: true,
@ -88,7 +88,7 @@ const state: OnboardingState = {
},
{
name: 'analytics',
label: 'Analytics & Bug report:translated',
label: 'Analytics & Bug report',
options: {
showFooter: false,
showBackground: true,

2
src/reducers/settings.js

@ -7,7 +7,7 @@ import {
listCryptoCurrencies,
} from '@ledgerhq/live-common/lib/helpers/currencies'
import { createSelector } from 'reselect'
import type { Selector } from 'reselect'
import type { InputSelector as Selector } from 'reselect'
import type { CryptoCurrency, Currency, Account } from '@ledgerhq/live-common/lib/types'
import type { Settings, CurrencySettings } from 'types/common'

1
static/i18n/en/common.yml

@ -1,6 +1,7 @@
ok: Okay
confirm: Confirm
cancel: Cancel
continue: Continue
chooseWalletPlaceholder: Choose a wallet...
currency: Currency
selectAccount: Select an account

48
static/i18n/en/onboarding.yml

@ -0,0 +1,48 @@
start:
title: Welcome to the new Ledger Live Desktop app.
desc: Let’s get started!
init:
title: Welcome to Ledger Live, the computer companion app to your Ledger device. Please select one of the options below
newDevice:
title: Initialize your new Ledger device
desc: Please replace it with the final wording once it’s done.
restoreDevice:
title: Restore a Ledger device
desc: Please replace it with the final wording once it’s done.
initializedDevice:
title: I have already initialized my device
desc: Please replace it with the final wording once it’s done.
noDevice:
title: Do not have a Ledger device yet? Buy one
desc: Please replace it with the final wording once it’s done.
selectDevice:
title: To get started, select your device
desc: This is a long text, please replace it with the final wording once it’s done. Lorem ipsum dolor amet ledger lorem dolor ipsum amet
ledgerNanoCard:
title: Ledger Nano S
desc: Please replace it with the final wording once it’s done.
ledgerBlueCard:
title: Ledger Blue
desc: Please replace it with the final wording once it’s done.
selectPIN:
title: Select PIN code
desc: This is a long text, please replace it with the final wording once it’s done. Lorem ipsum dolor amet ledger lorem dolor ipsum amet
instructions:
step1: Connect your Ledger Nano S to your computer using the supplied micro USB cable.
step2: Press both buttons simultaneously as instructed on your Ledger Nano S screen.
step3: Select Configure as new device on your Ledger Nano S by pressing the right button, located above the validation icon.
step4: Choose a PIN code between 4 and 8 digits long.
writeSeed:
title: 24-Word Recovery phrase
desc: The 24 words that constitute your recovery phrase will now be displayed one by one on the Ledger Nano S screen. These 24 words will be displayed only once during this initialization.
instructions:
step1: Copy the first word (Word \#1) in position 1 on the blank Recovery sheet included in the box.
step2: Move to Word \#2 by pressing the right button, copy it in position 2 on the Recovery sheet.
step3: Repeat the process until all 24 words are copied on the Recovery sheet.
step4: To confirm, use the right or left button to select each of the 24 words in the right order.
step5: Validate each word by simultaneously pressing both buttons.
finish:
title: This is the title of the screen. 1 line is the maximum
desc: This is a long text, please replace it with the final wording once it’s done.
Lorem ipsum dolor amet ledger lorem dolor ipsum amet
openAppButton: Open app
followUsLabel: Follow us to stay updated

164
yarn.lock

@ -1712,7 +1712,7 @@
version "8.10.11"
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.11.tgz#971ea8cb91adbe0b74e3fbd867dec192d5893a5f"
"@types/webpack-env@^1.13.5":
"@types/webpack-env@^1.13.6":
version "1.13.6"
resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.13.6.tgz#128d1685a7c34d31ed17010fc87d6a12c1de6976"
@ -1833,6 +1833,15 @@ ajv@^6.0.1, ajv@^6.1.0, ajv@^6.1.1, ajv@^6.4.0:
json-schema-traverse "^0.3.0"
uri-js "^3.0.2"
ajv@^6.4.0:
version "6.5.0"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.5.0.tgz#4c8affdf80887d8f132c9c52ab8a2dc4d0b7b24c"
dependencies:
fast-deep-equal "^2.0.1"
fast-json-stable-stringify "^2.0.0"
json-schema-traverse "^0.3.0"
uri-js "^4.2.1"
align-text@^0.1.1, align-text@^0.1.3:
version "0.1.4"
resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117"
@ -2135,7 +2144,7 @@ async@^1.4.0, async@^1.5.0, async@^1.5.2:
version "1.5.2"
resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a"
async@^2.1.2, async@^2.1.4, async@^2.4.1, async@^2.6.0:
async@^2.1.2, async@^2.1.4, async@^2.6.0:
version "2.6.0"
resolved "https://registry.yarnpkg.com/async/-/async-2.6.0.tgz#61a29abb6fcc026fea77e56d1c6ec53a795951f4"
dependencies:
@ -4519,7 +4528,7 @@ css-color-names@0.0.4:
version "0.0.4"
resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0"
css-hot-loader@^1.3.8:
css-hot-loader@^1.3.9:
version "1.3.9"
resolved "https://registry.yarnpkg.com/css-hot-loader/-/css-hot-loader-1.3.9.tgz#ed22b41126920134a4a2246d7d32113e2425c754"
dependencies:
@ -5420,6 +5429,15 @@ electron-devtools-installer@^2.2.3:
rimraf "^2.5.2"
semver "^5.3.0"
electron-devtools-installer@^2.2.4:
version "2.2.4"
resolved "https://registry.yarnpkg.com/electron-devtools-installer/-/electron-devtools-installer-2.2.4.tgz#261a50337e37121d338b966f07922eb4939a8763"
dependencies:
"7zip" "0.0.6"
cross-unzip "0.0.2"
rimraf "^2.5.2"
semver "^5.3.0"
electron-download-tf@4.3.4:
version "4.3.4"
resolved "https://registry.yarnpkg.com/electron-download-tf/-/electron-download-tf-4.3.4.tgz#b03740b2885aa2ad3f8784fae74df427f66d5165"
@ -5526,7 +5544,7 @@ electron-updater@^2.21.8:
semver "^5.5.0"
source-map-support "^0.5.5"
electron-webpack-js@~2.0.0:
electron-webpack-js@~2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/electron-webpack-js/-/electron-webpack-js-2.0.2.tgz#2a4d2274fc02e917396d8d9699f831554f6ebd2d"
dependencies:
@ -5536,35 +5554,35 @@ electron-webpack-js@~2.0.0:
babel-plugin-component "^1.1.0"
babel-plugin-syntax-dynamic-import "^7.0.0-beta.3"
electron-webpack@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/electron-webpack/-/electron-webpack-2.0.1.tgz#4b1f02ccd685cc5bbd16b300e68b00a256e38ad2"
electron-webpack@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/electron-webpack/-/electron-webpack-2.1.0.tgz#d229cdf8baca006bf9c360ba11e352f799f4004a"
dependencies:
"@types/webpack-env" "^1.13.5"
"@types/webpack-env" "^1.13.6"
async-exit-hook "^2.0.1"
bluebird-lst "^1.0.5"
chalk "^2.3.2"
chalk "^2.4.1"
crocket "^0.9.11"
css-hot-loader "^1.3.8"
css-hot-loader "^1.3.9"
css-loader "^0.28.11"
debug "^3.1.0"
electron-devtools-installer "^2.2.3"
electron-webpack-js "~2.0.0"
extract-text-webpack-plugin "^4.0.0-beta.0"
electron-devtools-installer "^2.2.4"
electron-webpack-js "~2.0.2"
file-loader "^1.1.11"
fs-extra-p "^4.5.2"
fs-extra-p "^4.6.0"
html-loader "^1.0.0-alpha.0"
html-webpack-plugin "^3.1.0"
html-webpack-plugin "^3.2.0"
lazy-val "^1.0.3"
mini-css-extract-plugin "^0.4.0"
node-loader "^0.6.0"
read-config-file "^3.0.0"
read-config-file "^3.0.1"
semver "^5.5.0"
source-map-support "^0.5.4"
style-loader "^0.20.3"
uglifyjs-webpack-plugin "^1.2.4"
source-map-support "^0.5.5"
style-loader "^0.21.0"
uglifyjs-webpack-plugin "^1.2.5"
url-loader "^1.0.1"
webpack-cli "^2.0.13"
webpack-dev-server "^3.1.1"
webpack-cli "^2.1.3"
webpack-dev-server "^3.1.4"
webpack-merge "^4.1.2"
yargs "^11.1.0"
@ -6160,15 +6178,6 @@ extglob@^2.0.4:
snapdragon "^0.8.1"
to-regex "^3.0.1"
extract-text-webpack-plugin@^4.0.0-beta.0:
version "4.0.0-beta.0"
resolved "https://registry.yarnpkg.com/extract-text-webpack-plugin/-/extract-text-webpack-plugin-4.0.0-beta.0.tgz#f7361d7ff430b42961f8d1321ba8c1757b5d4c42"
dependencies:
async "^2.4.1"
loader-utils "^1.1.0"
schema-utils "^0.4.5"
webpack-sources "^1.1.0"
extract-zip@^1.0.3:
version "1.6.6"
resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-1.6.6.tgz#1290ede8d20d0872b429fd3f351ca128ec5ef85c"
@ -6190,6 +6199,10 @@ fast-deep-equal@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz#c053477817c86b51daa853c81e059b733d023614"
fast-deep-equal@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49"
fast-glob@^2.0.2:
version "2.2.1"
resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-2.2.1.tgz#686c2345be88f3741e174add0be6f2e5b6078889"
@ -6486,6 +6499,13 @@ fs-extra-p@^4.5.0, fs-extra-p@^4.5.2, fs-extra-p@^4.6.0:
bluebird-lst "^1.0.5"
fs-extra "^6.0.0"
fs-extra-p@^4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/fs-extra-p/-/fs-extra-p-4.6.0.tgz#c7b7117f0dcf8a99c9b2ed589067c960abcf3ef9"
dependencies:
bluebird-lst "^1.0.5"
fs-extra "^6.0.0"
fs-extra@^0.30.0:
version "0.30.0"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.30.0.tgz#f233ffcc08d4da7d432daa449776989db1df93f0"
@ -6521,8 +6541,13 @@ fs-extra@^5.0.0:
universalify "^0.1.0"
fs-extra@^6.0.0:
<<<<<<< HEAD
version "6.0.0"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-6.0.0.tgz#0f0afb290bb3deb87978da816fcd3c7797f3a817"
=======
version "6.0.1"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-6.0.1.tgz#8abc128f7946e310135ddc93b98bddb410e7a34b"
>>>>>>> master
dependencies:
graceful-fs "^4.1.2"
jsonfile "^4.0.0"
@ -7170,7 +7195,7 @@ html-webpack-plugin@^2.30.1:
pretty-error "^2.0.2"
toposort "^1.0.0"
html-webpack-plugin@^3.1.0:
html-webpack-plugin@^3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-3.2.0.tgz#b01abbd723acaaa7b37b6af4492ebda03d9dd37b"
dependencies:
@ -8494,6 +8519,7 @@ lcid@^1.0.0:
dependencies:
invert-kv "^1.0.0"
<<<<<<< HEAD
ledger-core@meriadec/lib-ledger-core-node-bindings#697ec09:
version "1.0.0"
resolved "https://codeload.github.com/meriadec/lib-ledger-core-node-bindings/tar.gz/697ec09daa223a40a04267239c70a9a0e82cb15f"
@ -8506,6 +8532,13 @@ ledger-core@meriadec/lib-ledger-core-node-bindings#697ec09:
nan "^2.6.2"
npm "^5.7.1"
prebuild-install "^2.2.2"
=======
ledger-test-library@MortalKastor/ledger-test-library-nodejs#d782241:
version "1.0.0"
resolved "https://codeload.github.com/MortalKastor/ledger-test-library-nodejs/tar.gz/d782241ab1fd227c891b55c77e802fd76b8474bb"
dependencies:
axios "^0.17.1"
>>>>>>> master
left-pad@^1.2.0:
version "1.3.0"
@ -9100,6 +9133,13 @@ min-document@^2.19.0:
dependencies:
dom-walk "^0.1.0"
mini-css-extract-plugin@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-0.4.0.tgz#ff3bf08bee96e618e177c16ca6131bfecef707f9"
dependencies:
loader-utils "^1.1.0"
webpack-sources "^1.1.0"
minimalistic-assert@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7"
@ -11239,12 +11279,15 @@ read-chunk@^2.1.0:
pify "^3.0.0"
safe-buffer "^5.1.1"
<<<<<<< HEAD
read-cmd-shim@^1.0.1, read-cmd-shim@~1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/read-cmd-shim/-/read-cmd-shim-1.0.1.tgz#2d5d157786a37c055d22077c32c53f8329e91c7b"
dependencies:
graceful-fs "^4.1.2"
=======
>>>>>>> master
read-config-file@3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/read-config-file/-/read-config-file-3.0.0.tgz#771def5184a7f76abaf6b2c82f20cb983775b8ea"
@ -11259,7 +11302,11 @@ read-config-file@3.0.0:
json5 "^0.5.1"
lazy-val "^1.0.3"
<<<<<<< HEAD
read-config-file@^3.0.0:
=======
read-config-file@^3.0.1:
>>>>>>> master
version "3.0.1"
resolved "https://registry.yarnpkg.com/read-config-file/-/read-config-file-3.0.1.tgz#307ed2e162fa54306d0ae6d41e9cdc829720d2a9"
dependencies:
@ -11273,6 +11320,7 @@ read-config-file@^3.0.0:
json5 "^1.0.1"
lazy-val "^1.0.3"
<<<<<<< HEAD
read-installed@~4.0.3:
version "4.0.3"
resolved "https://registry.yarnpkg.com/read-installed/-/read-installed-4.0.3.tgz#ff9b8b67f187d1e4c29b9feb31f6b223acd19067"
@ -11307,6 +11355,8 @@ read-package-tree@~5.1.6:
read-package-json "^2.0.0"
readdir-scoped-modules "^1.0.0"
=======
>>>>>>> master
read-pkg-up@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02"
@ -12625,6 +12675,13 @@ style-loader@^0.20.3:
loader-utils "^1.1.0"
schema-utils "^0.4.5"
style-loader@^0.21.0:
version "0.21.0"
resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-0.21.0.tgz#68c52e5eb2afc9ca92b6274be277ee59aea3a852"
dependencies:
loader-utils "^1.1.0"
schema-utils "^0.4.5"
styled-components@^3.2.6:
version "3.2.6"
resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-3.2.6.tgz#99e6e75a746bdedd295a17e03dd1493055a1cc3b"
@ -13077,7 +13134,7 @@ uglifyjs-webpack-plugin@^0.4.6:
uglify-js "^2.8.29"
webpack-sources "^1.0.1"
uglifyjs-webpack-plugin@^1.2.4:
uglifyjs-webpack-plugin@^1.2.4, uglifyjs-webpack-plugin@^1.2.5:
version "1.2.5"
resolved "https://registry.yarnpkg.com/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.2.5.tgz#2ef8387c8f1a903ec5e44fa36f9f3cbdcea67641"
dependencies:
@ -13246,6 +13303,12 @@ uri-js@^3.0.2:
dependencies:
punycode "^2.1.0"
uri-js@^4.2.1:
version "4.2.1"
resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.1.tgz#4595a80a51f356164e22970df64c7abd6ade9850"
dependencies:
punycode "^2.1.0"
urix@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72"
@ -13526,7 +13589,7 @@ webpack-bundle-analyzer@^2.11.1:
opener "^1.4.3"
ws "^4.0.0"
webpack-cli@^2.0.13, webpack-cli@^2.0.14:
webpack-cli@^2.0.14:
version "2.1.2"
resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-2.1.2.tgz#9c9a4b90584f7b8acaf591238ef0667e04c817f6"
dependencies:
@ -13557,6 +13620,37 @@ webpack-cli@^2.0.13, webpack-cli@^2.0.14:
yeoman-environment "^2.0.0"
yeoman-generator "^2.0.4"
webpack-cli@^2.1.3:
version "2.1.3"
resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-2.1.3.tgz#65d166851abaa56067ef3f716b02a97ba6bbe84d"
dependencies:
chalk "^2.3.2"
cross-spawn "^6.0.5"
diff "^3.5.0"
enhanced-resolve "^4.0.0"
envinfo "^4.4.2"
glob-all "^3.1.0"
global-modules "^1.0.0"
got "^8.2.0"
import-local "^1.0.0"
inquirer "^5.1.0"
interpret "^1.0.4"
jscodeshift "^0.5.0"
listr "^0.13.0"
loader-utils "^1.1.0"
lodash "^4.17.5"
log-symbols "^2.2.0"
mkdirp "^0.5.1"
p-each-series "^1.0.0"
p-lazy "^1.0.0"
prettier "^1.5.3"
supports-color "^5.3.0"
v8-compile-cache "^1.1.2"
webpack-addons "^1.1.5"
yargs "^11.1.0"
yeoman-environment "^2.0.0"
yeoman-generator "^2.0.4"
webpack-core@~0.6.0:
version "0.6.9"
resolved "https://registry.yarnpkg.com/webpack-core/-/webpack-core-0.6.9.tgz#fc571588c8558da77be9efb6debdc5a3b172bdc2"
@ -13586,7 +13680,11 @@ webpack-dev-middleware@^1.12.2:
range-parser "^1.0.3"
time-stamp "^2.0.0"
<<<<<<< HEAD
webpack-dev-server@^3.1.1:
=======
webpack-dev-server@^3.1.4:
>>>>>>> master
version "3.1.4"
resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-3.1.4.tgz#9a08d13c4addd1e3b6d8ace116e86715094ad5b4"
dependencies:

Loading…
Cancel
Save