From 833c013fc2d8fa840579208bcc5a0963f4632a17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Renaudeau?= <gaetan.renaudeau@ledger.fr> Date: Mon, 16 Jul 2018 15:21:20 +0200 Subject: [PATCH 1/2] Fixes #1152 --- src/components/Onboarding/index.js | 17 +++++------------ src/components/OnboardingOrElse.js | 11 +++++++---- .../SettingsPage/LaunchOnboardingBtn.js | 12 ++---------- src/components/layout/Default.js | 8 ++++---- src/reducers/onboarding.js | 12 ++++++++---- 5 files changed, 26 insertions(+), 34 deletions(-) diff --git a/src/components/Onboarding/index.js b/src/components/Onboarding/index.js index 18a172be..7c489606 100644 --- a/src/components/Onboarding/index.js +++ b/src/components/Onboarding/index.js @@ -20,6 +20,7 @@ import { updateGenuineCheck, isLedgerNano, flowType, + relaunchOnboarding, } from 'reducers/onboarding' import { getCurrentDevice } from 'reducers/devices' @@ -66,6 +67,7 @@ const mapDispatchToProps = { jumpStep, unlock, openModal, + relaunchOnboarding, } type Props = { @@ -80,6 +82,7 @@ type Props = { getCurrentDevice: Function, unlock: Function, openModal: string => void, + relaunchOnboarding: boolean => void, } export type StepProps = { @@ -103,6 +106,7 @@ class Onboarding extends PureComponent<Props> { getDeviceInfo = () => this.props.getCurrentDevice finish = () => { this.props.saveSettings({ hasCompletedOnboarding: true }) + this.props.relaunchOnboarding(false) setTimeout(() => { this.props.openModal(MODAL_DISCLAIMER) }, MODAL_DISCLAIMER_DELAY) @@ -118,18 +122,7 @@ class Onboarding extends PureComponent<Props> { } render() { - const { - hasCompletedOnboarding, - onboarding, - prevStep, - nextStep, - jumpStep, - settings, - t, - } = this.props - if (hasCompletedOnboarding) { - return null - } + const { onboarding, prevStep, nextStep, jumpStep, settings, t } = this.props const StepComponent = STEPS[onboarding.stepName] const step = onboarding.steps[onboarding.stepIndex] diff --git a/src/components/OnboardingOrElse.js b/src/components/OnboardingOrElse.js index f82a9418..6b7ce709 100644 --- a/src/components/OnboardingOrElse.js +++ b/src/components/OnboardingOrElse.js @@ -4,25 +4,28 @@ import React, { PureComponent } from 'react' import { connect } from 'react-redux' import { createStructuredSelector } from 'reselect' import { hasCompletedOnboardingSelector } from 'reducers/settings' +import { onboardingRelaunchedSelector } from 'reducers/onboarding' import Onboarding from './Onboarding' type Props = { hasCompletedOnboarding: boolean, + onboardingRelaunched: boolean, children: *, } class OnboardingOrElse extends PureComponent<Props> { render() { - const { hasCompletedOnboarding, children } = this.props - if (hasCompletedOnboarding) { - return children + const { hasCompletedOnboarding, onboardingRelaunched, children } = this.props + if (!hasCompletedOnboarding || onboardingRelaunched) { + return <Onboarding /> } - return <Onboarding /> + return children } } export default connect( createStructuredSelector({ hasCompletedOnboarding: hasCompletedOnboardingSelector, + onboardingRelaunched: onboardingRelaunchedSelector, }), )(OnboardingOrElse) diff --git a/src/components/SettingsPage/LaunchOnboardingBtn.js b/src/components/SettingsPage/LaunchOnboardingBtn.js index a63ba1b0..1d6174c7 100644 --- a/src/components/SettingsPage/LaunchOnboardingBtn.js +++ b/src/components/SettingsPage/LaunchOnboardingBtn.js @@ -2,32 +2,24 @@ import React, { Fragment, PureComponent } from 'react' import { connect } from 'react-redux' -import { saveSettings } from 'actions/settings' import { translate } from 'react-i18next' import type { T } from 'types/common' -import type { SettingsState } from 'reducers/settings' -import type { OnboardingState } from 'reducers/onboarding' import Track from 'analytics/Track' -import Onboarding from 'components/Onboarding' import Button from 'components/base/Button/index' import { relaunchOnboarding } from 'reducers/onboarding' const mapDispatchToProps = { - saveSettings, relaunchOnboarding, } type Props = { - saveSettings: ($Shape<SettingsState>) => void, - relaunchOnboarding: ($Shape<OnboardingState>) => void, + relaunchOnboarding: boolean => void, t: T, } class LaunchOnboardingBtn extends PureComponent<Props> { handleLaunchOnboarding = () => { - this.props.saveSettings({ hasCompletedOnboarding: false }) - this.props.relaunchOnboarding({ onboardingRelaunched: true }) - return <Onboarding /> + this.props.relaunchOnboarding(true) } render() { const { t } = this.props diff --git a/src/components/layout/Default.js b/src/components/layout/Default.js index 7e426ce0..5d70f1db 100644 --- a/src/components/layout/Default.js +++ b/src/components/layout/Default.js @@ -88,8 +88,8 @@ class Default extends Component<Props> { <ExportLogsBtn hookToShortcut /> <Track mandatory onMount event="App Starts" /> - <OnboardingOrElse> - <IsUnlocked> + <IsUnlocked> + <OnboardingOrElse> {Object.entries(modals).map(([name, ModalComponent]: [string, any]) => ( <ModalComponent key={name} /> ))} @@ -119,8 +119,8 @@ class Default extends Component<Props> { <KeyboardContent sequence="BJBJBJ"> <PerfIndicator /> </KeyboardContent> - </IsUnlocked> - </OnboardingOrElse> + </OnboardingOrElse> + </IsUnlocked> </Fragment> ) } diff --git a/src/reducers/onboarding.js b/src/reducers/onboarding.js index 4785cd19..44fc65d0 100644 --- a/src/reducers/onboarding.js +++ b/src/reducers/onboarding.js @@ -2,6 +2,7 @@ import { SKIP_ONBOARDING } from 'config/constants' import { handleActions, createAction } from 'redux-actions' +import type { State } from '.' type Step = { name: string, @@ -170,14 +171,17 @@ const handlers = { ...state, isLedgerNano, }), - ONBOARDING_RELAUNCH: ( - state: OnboardingState, - { payload: onboardingRelaunched }: { payload: $Shape<OnboardingState> }, - ) => ({ ...initialState, ...onboardingRelaunched }), + ONBOARDING_RELAUNCH: (state: OnboardingState, { payload: onboardingRelaunched }) => ({ + ...initialState, + onboardingRelaunched, + }), } export default handleActions(handlers, initialState) +export const onboardingRelaunchedSelector = (s: State): ?boolean => + s.onboarding.onboardingRelaunched + export const relaunchOnboarding = createAction('ONBOARDING_RELAUNCH') export const nextStep = createAction('ONBOARDING_NEXT_STEP') export const prevStep = createAction('ONBOARDING_PREV_STEP') From 462a82be6b0878d2557052d33b166dca6a94b402 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Renaudeau?= <gaetan.renaudeau@ledger.fr> Date: Mon, 16 Jul 2018 15:47:40 +0200 Subject: [PATCH 2/2] Fixes #1146 --- src/components/Onboarding/index.js | 41 +++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/src/components/Onboarding/index.js b/src/components/Onboarding/index.js index 7c489606..11510a8a 100644 --- a/src/components/Onboarding/index.js +++ b/src/components/Onboarding/index.js @@ -5,6 +5,7 @@ import { compose } from 'redux' import { translate } from 'react-i18next' import { connect } from 'react-redux' import styled from 'styled-components' +import IconCross from 'icons/Cross' import type { T } from 'types/common' import type { OnboardingState } from 'reducers/onboarding' @@ -21,6 +22,7 @@ import { isLedgerNano, flowType, relaunchOnboarding, + onboardingRelaunchedSelector, } from 'reducers/onboarding' import { getCurrentDevice } from 'reducers/devices' @@ -55,6 +57,7 @@ const STEPS = { const mapStateToProps = state => ({ hasCompletedOnboarding: state.settings.hasCompletedOnboarding, + onboardingRelaunched: onboardingRelaunchedSelector(state), onboarding: state.onboarding, settings: state.settings, getCurrentDevice: getCurrentDevice(state), @@ -73,6 +76,7 @@ const mapDispatchToProps = { type Props = { t: T, hasCompletedOnboarding: boolean, + onboardingRelaunched: boolean, saveSettings: Function, onboarding: OnboardingState, settings: SettingsState, @@ -102,8 +106,30 @@ export type StepProps = { flowType: Function, } +const CloseContainer = styled(Box).attrs({ + p: 4, + color: 'fog', +})` + cursor: pointer; + position: absolute; + top: 0; + right: 0; + z-index: 1; + + &:hover { + color: ${p => p.theme.colors.grey}; + } + + &:active { + color: ${p => p.theme.colors.dark}; + } +` + class Onboarding extends PureComponent<Props> { getDeviceInfo = () => this.props.getCurrentDevice + cancelRelaunch = () => { + this.props.relaunchOnboarding(false) + } finish = () => { this.props.saveSettings({ hasCompletedOnboarding: true }) this.props.relaunchOnboarding(false) @@ -122,7 +148,15 @@ class Onboarding extends PureComponent<Props> { } render() { - const { onboarding, prevStep, nextStep, jumpStep, settings, t } = this.props + const { + onboarding, + prevStep, + nextStep, + jumpStep, + settings, + t, + onboardingRelaunched, + } = this.props const StepComponent = STEPS[onboarding.stepName] const step = onboarding.steps[onboarding.stepIndex] @@ -152,6 +186,11 @@ class Onboarding extends PureComponent<Props> { return ( <Container> {step.options.showBreadcrumb && <OnboardingBreadcrumb />} + {onboardingRelaunched ? ( + <CloseContainer onClick={this.cancelRelaunch}> + <IconCross size={16} /> + </CloseContainer> + ) : null} <StepContainer> <StepComponent {...stepProps} /> </StepContainer>