Skip to content
This repository has been archived by the owner on Jun 16, 2022. It is now read-only.

LIVE-2240 - Feat - Reborn onboarding #2514

Open
wants to merge 1 commit into
base: feat/LIVE-1813-reborn
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added assets/images/devices/3DRenderVertical.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/images/onboarding/stories/slide1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/images/onboarding/stories/slide2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/images/onboarding/stories/slide3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/images/onboarding/stories/slide4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions src/components/RootNavigator/OnboardingNavigator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import OnboardingSyncDesktopInformation from "../../screens/Onboarding/steps/set
import OnboardingRecoveryPhraseWarning from "../../screens/Onboarding/steps/setupDevice/drawers/RecoveryPhraseWarning";
import PostWelcomeSelection from "../../screens/Onboarding/steps/postWelcomeSelection";
import BuyDeviceScreen from "../../screens/BuyDeviceScreen";
import OnboardingStepDoYouHaveALedgerDevice from "../../screens/Onboarding/steps/doYouHaveALedger";

const Stack = createStackNavigator();
const OnboardingCarefulWarningStack = createStackNavigator();
Expand Down Expand Up @@ -193,6 +194,10 @@ export default function OnboardingNavigator() {
component={OnboardingPreQuizModalNavigator}
options={modalOptions}
/>
<Stack.Screen
name={ScreenName.OnboardingDoYouHaveALedgerDevice}
component={OnboardingStepDoYouHaveALedgerDevice}
/>
<Stack.Screen
name={ScreenName.OnboardingModalDiscoverLive}
component={OnboardingNewDiscoverLiveInfo}
Expand Down
1 change: 1 addition & 0 deletions src/const/navigation.js
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ export const ScreenName = {
LendingWithdrawValidationSuccess: "Lend WithdrawValidationSuccess",

OnboardingWelcome: "OnboardingWelcome",
OnboardingDoYouHaveALedgerDevice: "OnboardingStepDoYouHaveALedgerDevice",
OnboardingPostWelcomeSelection: "OnboardingPostWelcomeSelection",
OnboardingLanguage: "OnboardingLanguage",
OnboardingStepLanguageGetStarted: "OnboardingStepLanguageGetStarted",
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 12 additions & 2 deletions src/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -841,6 +841,10 @@
"privacyLink": "Privacy Policy",
"and": "and"
},
"stepDoYouHaveALedgerDevice": {
"title": "Do you have a ledger device ?",
"subtitle": "First things first"
},
"postWelcomeStep": {
"title": "Let’s get started",
"subtitle": "Set up your Ledger or buy one now.",
Expand All @@ -854,11 +858,13 @@
"subtitle": "Your key to Web3 — Unlock the freedom to control your assets"
},
"discoverLedger": {
"title": "Discover Ledger Live",
"subtitle": "Explore the app"
"title": "Explore Ledger Live",
"subtitle": "Explore the app and learn about its benefits "
}
},
"discoverLive": {
"exploreWithoutADevice": "Explore without a device",
"buyALedgerNow": "Buy a Ledger now",
"0": {
"title": "One place for all your crypto needs",
"desc": "Monitor, buy, sell, swap, grow and manage your assets securely and get the best crypto insights"
Expand All @@ -871,6 +877,10 @@
"title": "Reclaim power over your money",
"desc": "The Ledger Nano X keeps your coins offline and protected. Combine it to Ledger Live app for maximum security and control over your crypto",
"cta": "Begin your Journey"
},
"3": {
"title": "One place for all your crypto needs",
"desc": "Monitor, buy, sell, swap, grow and manage your assets securely and get the best crypto insights"
}
},
"stepLanguage": {
Expand Down
207 changes: 115 additions & 92 deletions src/screens/Onboarding/steps/discoverLiveInfo.tsx
Original file line number Diff line number Diff line change
@@ -1,129 +1,152 @@
import React, { useCallback, useState } from "react";
import * as Animatable from "react-native-animatable";
import React, { useCallback } from "react";
import { useTranslation } from "react-i18next";
import { Flex, Carousel, Text, Button, Icons } from "@ledgerhq/native-ui";
import {
Flex,
Carousel,
Text,
Button,
StoriesIndicator,
Box,
} from "@ledgerhq/native-ui";
import { useNavigation } from "@react-navigation/native";
import { SafeAreaView } from "react-native-safe-area-context";
import styled from "styled-components/native";
import { useDispatch } from "react-redux";
import { completeOnboarding } from "../../../actions/settings";
import { useNavigationInterceptor } from "../onboardingContext";
import Svg, { Defs, LinearGradient, Rect, Stop } from "react-native-svg";
import { Image, ImageProps } from "react-native";
import { completeOnboarding, setReadOnlyMode } from "../../../actions/settings";

import { NavigatorName } from "../../../const";
import Illustration from "../../../images/illustration/Illustration";
import { NavigatorName, ScreenName } from "../../../const";

import { DeviceNames } from "../types";
const slidesImages = [
require("../../../../assets/images/onboarding/stories/slide1.png"),
require("../../../../assets/images/onboarding/stories/slide2.png"),
require("../../../../assets/images/onboarding/stories/slide3.png"),
require("../../../../assets/images/onboarding/stories/slide4.png"),
];

const StyledSafeAreaView = styled(SafeAreaView)`
flex: 1;
background-color: ${p => p.theme.colors.background.main};
padding: 16px;
`;

const images = {
light: [
require("../../../images/illustration/Light/_069.png"),
require("../../../images/illustration/Light/_073.png"),
require("../../../images/illustration/Light/_049.png"),
],
dark: [
require("../../../images/illustration/Dark/_069.png"),
require("../../../images/illustration/Dark/_073.png"),
require("../../../images/illustration/Dark/_049.png"),
],
};

type CardType = { index: number; deviceModelId: DeviceNames };
const Card = ({ index }: CardType) => {
const ChildContainer = styled(Flex).attrs({
flex: 1,
})``;

const Item = ({
title,
imageProps,
displayNavigationButtons = false,
}: {
title: string;
imageProps: ImageProps;
displayNavigationButtons?: boolean;
}) => {
const dispatch = useDispatch();
const navigation = useNavigation();
const { t } = useTranslation();
return (
<Flex flex={1} justifyContent="center" alignItems="center" px={20}>
<Flex mb={10}>
<Illustration
size={248}
darkSource={images.dark[index]}
lightSource={images.light[index]}
/>
</Flex>
<Text variant="h2" mb={3} style={{ textTransform: "uppercase" }}>
{t(`onboarding.discoverLive.${index}.title`)}
</Text>
<Text textAlign="center" variant="body">
{t(`onboarding.discoverLive.${index}.desc`)}
</Text>
</Flex>
);
};

const FooterNextButton = ({ label }: { label: string }) => {
const navigation = useNavigation();
const dispatch = useDispatch();
const { resetCurrentStep } = useNavigationInterceptor();
const buyLedger = useCallback(() => {
// TODO: FIX @react-navigation/native using Typescript
// @ts-ignore next-line
navigation.navigate(ScreenName.BuyDeviceScreen);
}, [navigation]);

function next(): void {
const exploreLedger = useCallback(() => {
dispatch(completeOnboarding());
resetCurrentStep();

const parentNav = navigation.getParent();
if (parentNav) {
parentNav.popToTop();
}
dispatch(setReadOnlyMode(true));

// Fixme: Navigate to read only page ?
// TODO: FIX @react-navigation/native using Typescript
// @ts-ignore next-line
navigation.replace(NavigatorName.Base, {
navigation.navigate(NavigatorName.Base, {
screen: NavigatorName.Main,
});
}
}, [navigation]);

return (
<Button type="main" size="large" onPress={next}>
{label}
</Button>
);
};

const FooterActions = new Map();
FooterActions.set(2, FooterNextButton);

const Footer = ({ index }: { index: number }) => {
const { t } = useTranslation();

const Component = FooterActions.get(index);
if (!Component) return null;

return (
<Animatable.View animation="fadeIn" useNativeDriver>
<Component label={t(`onboarding.discoverLive.${index}.cta`)} />
</Animatable.View>
<ChildContainer backgroundColor={`neutral.c20`}>
<Svg width="100%" height={102} preserveAspectRatio="xMinYMin slice">
<Defs>
<LinearGradient
id="myGradient"
x1="0%"
y1="0%"
x2="0%"
y2="100%"
gradientUnits="userSpaceOnUse"
>
<Stop offset="0%" stopOpacity={1} stopColor="black" />
<Stop offset="100%" stopOpacity={0} stopColor="black" />
</LinearGradient>
</Defs>
<Rect x="0" y="0" width="100%" height="100%" fill="url(#myGradient)" />
</Svg>
<Text
variant="h4"
style={{ fontSize: 40, lineHeight: 40 }}
mx={7}
mt={3}
mb={10}
>
{title}
</Text>
<Box
flex={1}
alignItems={"center"}
justifyContent={"flex-end"}
overflow={"hidden"}
>
<Image
resizeMode={"cover"}
style={{ flex: 1, width: "100%" }}
{...imageProps}
/>
</Box>
{displayNavigationButtons && (
<Box position={"absolute"} bottom={0} width={"100%"} px={6} pb={10}>
<Button onPress={exploreLedger} type={"main"} mb={6}>
{t("onboarding.discoverLive.exploreWithoutADevice")}
</Button>
<Button onPress={buyLedger} type={"shade"} outline={true}>
{t("onboarding.discoverLive.buyALedgerNow")}
</Button>
</Box>
)}
</ChildContainer>
);
};

function DiscoverLiveInfo() {
const [currentIndex, setCurrentIndex] = useState(0);
const navigation = useNavigation();

const handleBack = useCallback(() => navigation.goBack(), [navigation]);
const { t } = useTranslation();

return (
<StyledSafeAreaView>
<Flex
flexDirection="row"
justifyContent="space-between"
alignItems="center"
width="100%"
height={48}
<Carousel
autoDelay={6000}
scrollOnSidePress={true}
restartAfterEnd={false}
IndicatorComponent={StoriesIndicator}
slideIndicatorContainerProps={{
position: "absolute",
top: 0,
left: 0,
width: "100%",
px: 7,
}}
>
<Button Icon={Icons.ArrowLeftMedium} onPress={handleBack} />
</Flex>
<Carousel onChange={setCurrentIndex}>
{new Array(3).fill(null).map((_, index) => (
<Card index={index} key={index} />
{slidesImages.map((image, index) => (
<Item
key={index}
title={t(`onboarding.discoverLive.${index}.title`)}
imageProps={{
source: image,
}}
displayNavigationButtons={slidesImages.length - 1 === index}
/>
))}
</Carousel>
<Flex minHeight="13%" justifyContent="center" alignItems="center">
<Footer index={currentIndex} />
</Flex>
</StyledSafeAreaView>
);
}
Expand Down
75 changes: 75 additions & 0 deletions src/screens/Onboarding/steps/doYouHaveALedger.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import React, { useCallback } from "react";
import { useTranslation } from "react-i18next";
import { Box, Flex, Text } from "@ledgerhq/native-ui";
import { Image } from "react-native";
import { ScreenName } from "../../../const";
import StyledStatusBar from "../../../components/StyledStatusBar";
import Button from "../../../components/wrappedUi/Button";

const RenderVertical = require("../../../../assets/images/devices/3DRenderVertical.png");

function OnboardingStepDoYouHaveALedgerDevice({ navigation }: any) {
const { t } = useTranslation();

const nextHaveALedger = useCallback(() => {
// TODO: FIX @react-navigation/native using Typescript
// @ts-ignore next-line
navigation.navigate({
name: ScreenName.OnboardingPostWelcomeSelection,
params: {
userHasDevice: true,
},
});
}, [navigation]);

const nextDontHaveALedger = useCallback(() => {
// TODO: FIX @react-navigation/native using Typescript
// @ts-ignore next-line
navigation.navigate({
name: ScreenName.OnboardingPostWelcomeSelection,
params: {
userHasDevice: false,
},
});
}, [navigation]);

return (
<Flex flex={1}>
<StyledStatusBar barStyle="light-content" />
<Box flex={1} justifyContent="center" alignItems="center" mt={8} mx={7}>
<Image
source={RenderVertical}
resizeMode={"contain"}
style={{ flex: 1, width: "100%" }}
/>
</Box>
<Flex px={6} pb={6}>
<Text variant="large" fontWeight="medium" color="neutral.c70" pb={2}>
{t("onboarding.stepDoYouHaveALedgerDevice.subtitle")}
</Text>
<Text variant="h4" color="neutral.c100" pb={8}>
{t("onboarding.stepDoYouHaveALedgerDevice.title")}
</Text>
<Button
type="main"
size="large"
event="Onboarding - Start"
onPress={nextHaveALedger}
mb={6}
>
{t("common.yes")}
</Button>
<Button
type="main"
size="large"
event="Onboarding - Start"
onPress={nextDontHaveALedger}
>
{t("common.no")}
</Button>
</Flex>
</Flex>
);
}

export default OnboardingStepDoYouHaveALedgerDevice;
Loading