Skip to content

Commit 551157e

Browse files
committed
feat(suite-native): onboarding biometrics screen
1 parent a55e612 commit 551157e

File tree

10 files changed

+150
-16
lines changed

10 files changed

+150
-16
lines changed

suite-native/biometrics/src/useBiometricsSettings.ts

+9-7
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,15 @@ export const useBiometricsSettings = () => {
2323
const isBiometricsAvailable = await getIsBiometricsFeatureAvailable();
2424

2525
if (!isBiometricsAvailable) {
26-
showAlert({
27-
title: 'Biometrics',
28-
description:
29-
'No security features on your device. Make sure you have biometrics setup on your phone and try again.',
30-
primaryButtonTitle: 'Cancel',
31-
onPressPrimaryButton: () => null,
32-
pictogramVariant: 'warning',
26+
await new Promise(resolve => {
27+
showAlert({
28+
title: 'Biometrics',
29+
description:
30+
'No security features on your device. Make sure you have biometrics setup on your phone and try again.',
31+
primaryButtonTitle: 'Cancel',
32+
onPressPrimaryButton: () => resolve(undefined),
33+
pictogramVariant: 'warning',
34+
});
3335
});
3436

3537
return 'notAvailable';

suite-native/intl/src/en.ts

+9-1
Original file line numberDiff line numberDiff line change
@@ -70,12 +70,13 @@ export const en = {
7070
buttons: {
7171
receive: 'Receive',
7272
},
73+
74+
// TODO: delete this when is the new welcome flow enabled by default
7375
biometricsModal: {
7476
title: 'Enable biometrics protection',
7577
description: 'You can always change this later.',
7678
button: {
7779
later: 'I’ll do that later in Settings',
78-
enable: 'Enable',
7980
},
8081
resultMsg: {
8182
error: 'Unable to enable biometrics',
@@ -834,6 +835,13 @@ export const en = {
834835
subtitleLegacy: 'Improve Trezor Suite Lite with your anonymous data.',
835836
learnMore: '<securityLink>More</securityLink> about privacy',
836837
},
838+
biometricsScreen: {
839+
title: 'Biometrics',
840+
description: 'Enable biometrics to prevent unauthorized access to this app.',
841+
button: {
842+
notNow: 'Not now',
843+
},
844+
},
837845
},
838846
moduleAccountManagement: {
839847
accountSettingsScreen: {

suite-native/module-home/src/screens/HomeScreen/useShowBiometricsAlert.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ export const useShowBiometricsAlert = () => {
5353

5454
const showBiometricsAlert = useCallback(() => {
5555
showAlert({
56-
primaryButtonTitle: <Translation id="moduleHome.biometricsModal.button.enable" />,
56+
primaryButtonTitle: <Translation id="generic.buttons.enable" />,
5757
onPressPrimaryButton: handleEnable,
5858
secondaryButtonTitle: <Translation id="moduleHome.biometricsModal.button.later" />,
5959
onPressSecondaryButton: handleCancel,

suite-native/module-onboarding/package.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
"type-check": "yarn g:tsc --build"
1111
},
1212
"dependencies": {
13+
"@react-navigation/core": "^6.4.10",
1314
"@react-navigation/native": "6.1.18",
1415
"@react-navigation/native-stack": "6.11.0",
1516
"@suite-native/atoms": "workspace:*",
@@ -20,6 +21,7 @@
2021
"@trezor/styles": "workspace:*",
2122
"expo-linear-gradient": "^14.0.1",
2223
"react": "18.2.0",
23-
"react-native": "0.76.1"
24+
"react-native": "0.76.1",
25+
"react-redux": "8.0.7"
2426
}
2527
}

suite-native/module-onboarding/src/navigation/OnboardingStackNavigator.tsx

+5
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88

99
import { WelcomeScreen } from '../screens/WelcomeScreen';
1010
import { AnalyticsConsentScreen } from '../screens/AnalyticsConsentScreen';
11+
import { BiometricsScreen } from '../screens/BiometricsScreen';
1112

1213
export const OnboardingStack = createNativeStackNavigator<OnboardingStackParamList>();
1314

@@ -21,5 +22,9 @@ export const OnboardingStackNavigator = () => (
2122
name={OnboardingStackRoutes.AnalyticsConsent}
2223
component={AnalyticsConsentScreen}
2324
/>
25+
<OnboardingStack.Screen
26+
name={OnboardingStackRoutes.Biometrics}
27+
component={BiometricsScreen}
28+
/>
2429
</OnboardingStack.Navigator>
2530
);

suite-native/module-onboarding/src/screens/AnalyticsConsentScreen.tsx

+10-6
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
import { useState } from 'react';
22

3-
import { Screen } from '@suite-native/navigation';
3+
import {
4+
OnboardingStackParamList,
5+
OnboardingStackRoutes,
6+
Screen,
7+
StackProps,
8+
} from '@suite-native/navigation';
49
import { Box, Button, Card, Switch, Text, TitleHeader, VStack } from '@suite-native/atoms';
510
import { Translation } from '@suite-native/intl';
611
import { prepareNativeStyle, useNativeStyles } from '@trezor/styles';
712
import { EventType, analytics } from '@suite-native/analytics';
813
import { useOpenLink } from '@suite-native/link';
9-
import { useToast } from '@suite-native/toasts';
1014

1115
import { AnalyticsInfoRow } from '../components/AnalyticsInfoRow';
1216

@@ -29,8 +33,9 @@ const reportAnalyticsOnboardingCompleted = (isTrackingAllowed: boolean) => {
2933
if (!isTrackingAllowed) analytics.disable();
3034
};
3135

32-
export const AnalyticsConsentScreen = () => {
33-
const { showToast } = useToast();
36+
export const AnalyticsConsentScreen = ({
37+
navigation,
38+
}: StackProps<OnboardingStackParamList, OnboardingStackRoutes.AnalyticsConsent>) => {
3439
const [isEnabled, setIsEnabled] = useState(true);
3540

3641
const { applyStyle } = useNativeStyles();
@@ -40,8 +45,7 @@ export const AnalyticsConsentScreen = () => {
4045
const handleRedirect = () => {
4146
reportAnalyticsOnboardingCompleted(isEnabled);
4247

43-
showToast({ variant: 'warning', message: 'TODO: implement next screen' });
44-
// navigation.navigate(OnboardingStackRoutes.Biometrics);
48+
navigation.navigate(OnboardingStackRoutes.Biometrics);
4549
};
4650

4751
const handleAnalyticsConsent = () => {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
import { useDispatch } from 'react-redux';
2+
3+
import { CommonActions } from '@react-navigation/core';
4+
5+
import { setIsOnboardingFinished } from '@suite-native/settings';
6+
import {
7+
HomeStackRoutes,
8+
OnboardingStackParamList,
9+
OnboardingStackRoutes,
10+
RootStackRoutes,
11+
Screen,
12+
ScreenHeader,
13+
StackProps,
14+
} from '@suite-native/navigation';
15+
import { Box, Button, HStack, Text, VStack } from '@suite-native/atoms';
16+
import { Translation } from '@suite-native/intl';
17+
import { EventType, analytics } from '@suite-native/analytics';
18+
import { BiometricsSvg, useBiometricsSettings } from '@suite-native/biometrics';
19+
import { Icon } from '@suite-native/icons';
20+
21+
export const BiometricsScreen = ({
22+
navigation,
23+
}: StackProps<OnboardingStackParamList, OnboardingStackRoutes.Biometrics>) => {
24+
const { toggleBiometricsOption } = useBiometricsSettings();
25+
26+
const dispatch = useDispatch();
27+
28+
const enableBiometrics = async () => {
29+
const result = await toggleBiometricsOption();
30+
if (result === 'enabled') {
31+
analytics.report({
32+
type: EventType.BiometricsChange,
33+
payload: {
34+
enabled: true,
35+
origin: 'bottomSheet',
36+
},
37+
});
38+
}
39+
};
40+
41+
const exitOnboardingFlow = () => {
42+
dispatch(setIsOnboardingFinished());
43+
44+
navigation.dispatch(
45+
CommonActions.reset({
46+
index: 0,
47+
routes: [
48+
{
49+
name: RootStackRoutes.AppTabs,
50+
params: {
51+
screen: HomeStackRoutes.Home,
52+
},
53+
},
54+
],
55+
}),
56+
);
57+
};
58+
59+
const handleEnableButtonPress = async () => {
60+
await enableBiometrics();
61+
exitOnboardingFlow();
62+
};
63+
64+
const handleNotNowButtonPress = () => {
65+
exitOnboardingFlow();
66+
};
67+
68+
return (
69+
<Screen header={<ScreenHeader />}>
70+
<VStack justifyContent="space-between" flex={1}>
71+
<Box flex={1} alignItems="center" paddingTop="sp32">
72+
<BiometricsSvg />
73+
</Box>
74+
<VStack spacing={40}>
75+
<VStack spacing="sp16">
76+
<HStack spacing="sp8" alignItems="center">
77+
<Icon
78+
name="fingerprint"
79+
color="textSecondaryHighlight"
80+
size="mediumLarge"
81+
/>
82+
<Text color="textSecondaryHighlight">
83+
<Translation id="moduleOnboarding.biometricsScreen.title" />
84+
</Text>
85+
</HStack>
86+
<Text variant="titleMedium">
87+
<Translation id="moduleOnboarding.biometricsScreen.description" />
88+
</Text>
89+
</VStack>
90+
<VStack spacing="sp12">
91+
<Button
92+
testID="@onboarding/UserDataConsent/enable"
93+
onPress={handleEnableButtonPress}
94+
>
95+
<Translation id="generic.buttons.enable" />
96+
</Button>
97+
<Button
98+
colorScheme="tertiaryElevation0"
99+
testID="@onboarding/Biometrics/skip"
100+
onPress={handleNotNowButtonPress}
101+
>
102+
<Translation id="moduleOnboarding.biometricsScreen.button.notNow" />
103+
</Button>
104+
</VStack>
105+
</VStack>
106+
</VStack>
107+
</Screen>
108+
);
109+
};

suite-native/navigation/src/navigators.ts

+1
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ export type LegacyOnboardingStackParamList = {
116116
export type OnboardingStackParamList = {
117117
[OnboardingStackRoutes.Welcome]: undefined;
118118
[OnboardingStackRoutes.AnalyticsConsent]: undefined;
119+
[OnboardingStackRoutes.Biometrics]: undefined;
119120
};
120121

121122
export type AccountsImportStackParamList = {

suite-native/navigation/src/routes.ts

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ export enum LegacyOnboardingStackRoutes {
3535
export enum OnboardingStackRoutes {
3636
Welcome = 'Welcome',
3737
AnalyticsConsent = 'AnalyticsConsent',
38+
Biometrics = 'Biometrics',
3839
}
3940

4041
export enum AccountsImportStackRoutes {

yarn.lock

+2
Original file line numberDiff line numberDiff line change
@@ -10814,6 +10814,7 @@ __metadata:
1081410814
version: 0.0.0-use.local
1081510815
resolution: "@suite-native/module-onboarding@workspace:suite-native/module-onboarding"
1081610816
dependencies:
10817+
"@react-navigation/core": "npm:^6.4.10"
1081710818
"@react-navigation/native": "npm:6.1.18"
1081810819
"@react-navigation/native-stack": "npm:6.11.0"
1081910820
"@suite-native/atoms": "workspace:*"
@@ -10825,6 +10826,7 @@ __metadata:
1082510826
expo-linear-gradient: "npm:^14.0.1"
1082610827
react: "npm:18.2.0"
1082710828
react-native: "npm:0.76.1"
10829+
react-redux: "npm:8.0.7"
1082810830
languageName: unknown
1082910831
linkType: soft
1083010832

0 commit comments

Comments
 (0)