Skip to content

Commit

Permalink
✨feat(llm): add scan WS qr code
Browse files Browse the repository at this point in the history
  • Loading branch information
LucasWerey committed Aug 6, 2024
1 parent f5f105d commit b2aaec1
Show file tree
Hide file tree
Showing 8 changed files with 178 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ type Props = {
buttonTitle: string;
onPress: () => void;
event: string;
hasNotBackground?: boolean;
};

const IconSettings = () => <Icon name="settings" size={16} color="neutral.c100" />;
Expand All @@ -22,11 +23,12 @@ const FallbackCameraBody: React.FC<Props> = ({
buttonTitle,
onPress,
event,
hasNotBackground,
}: Props) => {
const { colors } = useTheme();

return (
<Flex flex={1} bg="background.main" px={6}>
<Flex flex={1} bg={hasNotBackground ? null : "background.main"} px={6}>
<Flex flex={1} alignItems="center" justifyContent="center">
<FallbackCamera color={colors.constant.white} />
<Text variant="paragraph" mt={9} mb={3} fontSize={6}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ type Props = {
* context, rather than directly showing an error screen.
* */
optimisticallyMountChildren?: boolean;
fallBackHasNoBackground?: boolean;
};

/**
Expand All @@ -38,6 +39,7 @@ type Props = {
const RequiresCameraPermissions: React.FC<Props> = ({
children,
optimisticallyMountChildren = false,
fallBackHasNoBackground = false,
}) => {
const { t } = useTranslation();
const {
Expand All @@ -59,6 +61,7 @@ const RequiresCameraPermissions: React.FC<Props> = ({
<Fallback
event="CameraPressAuthorize"
onPress={requestPermission}
hasNotBackground={fallBackHasNoBackground}
title={t("permissions.camera.title")}
description={t("permissions.camera.authorizeDescription")}
buttonTitle={t("permissions.camera.authorizeButtonTitle")}
Expand All @@ -68,6 +71,7 @@ const RequiresCameraPermissions: React.FC<Props> = ({
<Fallback
event="CameraOpenSettings"
onPress={openAppSettings}
hasNotBackground={fallBackHasNoBackground}
title={t("permissions.camera.title")}
description={t("permissions.camera.goToSettingsDescription")}
buttonTitle={t("permissions.camera.goToSettingsButtonTitle")}
Expand Down
11 changes: 10 additions & 1 deletion apps/ledger-live-mobile/src/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -6805,7 +6805,16 @@
}
},
"scan": {
"title": "Scan"
"title": "Scan",
"description": "Scan QR code",
"explanation": {
"title": "Scan and synchronize your accounts using another Ledger Live app",
"steps": {
"step1": "Open the Ledger Live app you want to sync",
"step2": "Go to <0>Settings</0> <1>></1> <0>General</0> <1>></1> <0>Ledger Sync</0> <1>></1> <0>Synchronize</0> <1>></1> <0>Show QR</0>",
"step3": "Scan QR code until loader hits 100%."
}
}
},
"pinCode": {
"title": "Enter your code",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import React from "react";
import { ScrollContainer, Text, Flex } from "@ledgerhq/native-ui";
import { useTranslation } from "react-i18next";
import styled, { useTheme } from "styled-components/native";

type Props = {
steps: {
description: React.JSX.Element;
}[];
};

const BulletPoint = styled(Flex)`
width: 16px;
height: 16px;
justify-content: center;
align-items: center;
background-color: ${({ theme }) => theme.colors.primary.c80};
border-radius: 100px;
`;

const FlexContainer = styled(Flex)`
margin-bottom: 16px;
display: flex;
flex-direction: row;
align-items: flex-start;
gap: 12px;
`;

const BottomContainer = ({ steps }: Props) => {
const { colors } = useTheme();
const { t } = useTranslation();

return (
<ScrollContainer
px={16}
py={24}
background={colors.opacityDefault.c05}
borderRadius={24}
showsVerticalScrollIndicator={false}
maxHeight={200}
>
<Text variant="h4" fontSize={18} color={colors.neutral.c100} mb={24}>
{t("walletSync.synchronize.qrCode.scan.explanation.title")}
</Text>
<Flex width={"100%"} mb={32}>
{steps.map((step, index) => (
<FlexContainer key={index}>
<BulletPoint>
<Text fontSize={11} color={colors.neutral.c00}>
{index + 1}
</Text>
</BulletPoint>
<Flex>{step.description}</Flex>
</FlexContainer>
))}
</Flex>
</ScrollContainer>
);
};

export default BottomContainer;
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import React from "react";
import { Flex, Text, NumberedList, ScrollContainer } from "@ledgerhq/native-ui";
import { Flex, Text } from "@ledgerhq/native-ui";
import styled, { useTheme } from "styled-components/native";
import QRCode from "react-native-qrcode-svg";
import getWindowDimensions from "~/logic/getWindowDimensions";
import { Trans, useTranslation } from "react-i18next";
import BottomContainer from "./BottomContainer";

const Italic = styled(Text)`
font-style: italic;
Expand All @@ -26,14 +27,14 @@ const QrCode = ({ qrCodeValue }: Props) => {
const steps = [
{
description: (
<Text variant="body" flex={1} ml={12} fontSize={14} color={colors.opacityDefault.c70}>
<Text variant="body" flex={1} fontSize={14} color={colors.opacityDefault.c70}>
{t("walletSync.synchronize.qrCode.show.explanation.steps.step1")}
</Text>
),
},
{
description: (
<Text variant="body" flex={1} ml={12} fontSize={14} color={colors.opacityDefault.c70}>
<Text variant="body" flex={1} fontSize={14} color={colors.opacityDefault.c70}>
<Trans
i18nKey="walletSync.synchronize.qrCode.show.explanation.steps.step2"
components={[
Expand All @@ -46,7 +47,7 @@ const QrCode = ({ qrCodeValue }: Props) => {
},
{
description: (
<Text variant="body" flex={1} ml={12} fontSize={14} color={colors.opacityDefault.c70}>
<Text variant="body" flex={1} fontSize={14} color={colors.opacityDefault.c70}>
{t("walletSync.synchronize.qrCode.show.explanation.steps.step3")}
</Text>
),
Expand Down Expand Up @@ -79,20 +80,7 @@ const QrCode = ({ qrCodeValue }: Props) => {
size={QRCodeSize}
/>
</Flex>
<ScrollContainer
px={16}
mb={10}
width={"100%"}
maxHeight={280}
background={colors.opacityDefault.c05}
borderRadius={24}
showsVerticalScrollIndicator={false}
>
<Text variant="h4" fontSize={18} color={colors.neutral.c100} my={24}>
{t("walletSync.synchronize.qrCode.show.explanation.title")}
</Text>
<NumberedList items={steps} />
</ScrollContainer>
<BottomContainer steps={steps} />
</Flex>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import React from "react";
import { Flex, Icons, Text } from "@ledgerhq/native-ui";
import { Trans, useTranslation } from "react-i18next";
import styled, { useTheme } from "styled-components/native";
import BottomContainer from "./BottomContainer";
import { BarCodeScanningResult, Camera, CameraType } from "expo-camera";
import { BarCodeScanner } from "expo-barcode-scanner";
import ScanTargetSvg from "./ScanTargetSvg";
import RequiresCameraPermissions from "~/components/RequiresCameraPermissions";

const Italic = styled(Text)`
font-style: italic;
`;
// Won't work since we don't have inter italic font

const ScanQrCode = () => {
const { t } = useTranslation();
const { colors } = useTheme();

const steps = [
{
description: (
<Text variant="body" flex={1} fontSize={14} color={colors.opacityDefault.c70}>
{t("walletSync.synchronize.qrCode.scan.explanation.steps.step1")}
</Text>
),
},
{
description: (
<Text variant="body" flex={1} fontSize={14} color={colors.opacityDefault.c70}>
<Trans
i18nKey="walletSync.synchronize.qrCode.scan.explanation.steps.step2"
components={[
<Italic key={0} color={colors.opacityDefault.c70} />,
<Text key={1} color={colors.opacityDefault.c30} />,
]}
/>
</Text>
),
},
{
description: (
<Text variant="body" flex={1} fontSize={14} color={colors.opacityDefault.c70}>
{t("walletSync.synchronize.qrCode.scan.explanation.steps.step3")}
</Text>
),
},
];

return (
<Flex minHeight={400} justifyContent={"center"} alignItems={"center"} rowGap={24}>
<RequiresCameraPermissions optimisticallyMountChildren fallBackHasNoBackground>
<Flex>
<Camera
style={{ backgroundColor: colors.neutral.c50 }}
type={CameraType.back}
barCodeScannerSettings={{
barCodeTypes: [BarCodeScanner.Constants.BarCodeType.qr],
}}
onBarCodeScanned={({ data }: BarCodeScanningResult) => console.log(data)}
>
<ScanTargetSvg />
</Camera>
</Flex>
<Flex flexDirection={"row"} alignItems={"center"} columnGap={8}>
<Text variant="bodyLineHeight">
{t("walletSync.synchronize.qrCode.scan.description")}
</Text>
<Icons.QrCode />
</Flex>
<BottomContainer steps={steps} />
</RequiresCameraPermissions>
</Flex>
);
};

export default ScanQrCode;
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import * as React from "react";
import Svg, { SvgProps, Path } from "react-native-svg";
const ScanTargetSvg = (props: SvgProps) => (
<Svg width={289} height={289} fill="none" {...props}>
<Path
stroke="#fff"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={7}
d="M4 74.25V55.2c0-17.922 0-26.883 3.488-33.728A32 32 0 0 1 21.472 7.488C28.317 4 37.278 4 55.2 4h19.05M4 214.75v19.05c0 17.922 0 26.883 3.488 33.728a32 32 0 0 0 13.984 13.984C28.317 285 37.278 285 55.2 285h19.05m140.5 0h19.05c17.922 0 26.883 0 33.728-3.488a32 32 0 0 0 13.984-13.984C285 260.683 285 251.722 285 233.8v-19.05m0-140.5V55.2c0-17.922 0-26.883-3.488-33.728a32 32 0 0 0-13.984-13.984C260.683 4 251.722 4 233.8 4h-19.05"
/>
</Svg>
);
export default ScanTargetSvg;
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { useState } from "react";
import { Flex, TabSelector } from "@ledgerhq/native-ui";
import QrCode from "LLM/features/WalletSync/components/Synchronize/QrCode";
import ScanQrCode from "../../components/Synchronize/ScanQrCode";
import { Options, OptionsType } from "LLM/features/WalletSync/types/Activation";
import { useTranslation } from "react-i18next";
import {
Expand Down Expand Up @@ -31,14 +32,7 @@ const QrCodeMethod = () => {
return (
<>
<TrackScreen category={AnalyticsPage.ScanQRCode} />
<Flex
flexDirection={"column"}
rowGap={24}
alignItems={"center"}
width={100}
height={100}
bg={"red"}
/>
<ScanQrCode />
</>
);
case Options.SHOW_QR:
Expand All @@ -52,7 +46,7 @@ const QrCodeMethod = () => {
};

return (
<Flex flexDirection={"column"} alignItems={"center"} rowGap={24} pt={16} width={"100%"}>
<Flex flexDirection={"column"} alignItems={"center"} rowGap={24} width={"100%"}>
<TabSelector
options={[Options.SCAN, Options.SHOW_QR]}
selectedOption={selectedOption}
Expand Down

0 comments on commit b2aaec1

Please sign in to comment.