Skip to content

Commit 0bcd35b

Browse files
authored
feat(ui): add QuickPay prompt (#2402)
1 parent 3913667 commit 0bcd35b

File tree

4 files changed

+122
-0
lines changed

4 files changed

+122
-0
lines changed
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
import React, { memo, ReactElement, useEffect, useMemo } from 'react';
2+
import { useNavigation } from '@react-navigation/native';
3+
import { Trans, useTranslation } from 'react-i18next';
4+
5+
import { __E2E__ } from '../../constants/env';
6+
import { BodyMB, Display } from '../../styles/text';
7+
import BottomSheetWrapper from '../../components/BottomSheetWrapper';
8+
import BottomSheetScreen from '../../components/BottomSheetScreen';
9+
import { objectKeys } from '../../utils/objectKeys';
10+
import { useBalance } from '../../hooks/wallet';
11+
import { useAppDispatch, useAppSelector } from '../../hooks/redux';
12+
import {
13+
useBottomSheetBackPress,
14+
useSnapPoints,
15+
} from '../../hooks/bottomSheet';
16+
import { closeSheet } from '../../store/slices/ui';
17+
import { updateUser } from '../../store/slices/user';
18+
import { showBottomSheet } from '../../store/utils/ui';
19+
import { viewControllersSelector } from '../../store/reselect/ui';
20+
import { quickpayIntroSeenSelector } from '../../store/reselect/user';
21+
import { RootNavigationProp } from '../types';
22+
23+
const imageSrc = require('../../assets/illustrations/fast-forward.png');
24+
25+
const CHECK_DELAY = 3000; // how long user needs to stay on Wallets screen before he will see this prompt
26+
27+
const QuickPayPrompt = ({ enabled }: { enabled: boolean }): ReactElement => {
28+
const { t } = useTranslation('settings');
29+
const navigation = useNavigation<RootNavigationProp>();
30+
const { spendingBalance } = useBalance();
31+
const snapPoints = useSnapPoints('large');
32+
const dispatch = useAppDispatch();
33+
const viewControllers = useAppSelector(viewControllersSelector);
34+
const quickpayIntroSeen = useAppSelector(quickpayIntroSeenSelector);
35+
36+
useBottomSheetBackPress('quickPay');
37+
38+
const anyBottomSheetIsOpen = useMemo(() => {
39+
const viewControllerKeys = objectKeys(viewControllers);
40+
return viewControllerKeys
41+
.filter((view) => view !== 'quickPay')
42+
.some((view) => viewControllers[view].isOpen);
43+
}, [viewControllers]);
44+
45+
// if user hasn't seen this prompt
46+
// and has a spending balance
47+
// and no other bottom-sheets are shown
48+
// and user on "Wallets" screen for CHECK_DELAY
49+
const shouldShowBottomSheet = useMemo(() => {
50+
return (
51+
enabled &&
52+
!__E2E__ &&
53+
!anyBottomSheetIsOpen &&
54+
!quickpayIntroSeen &&
55+
spendingBalance > 0
56+
);
57+
}, [enabled, anyBottomSheetIsOpen, quickpayIntroSeen, spendingBalance]);
58+
59+
useEffect(() => {
60+
if (!shouldShowBottomSheet) {
61+
return;
62+
}
63+
64+
const timer = setTimeout(() => {
65+
showBottomSheet('quickPay');
66+
}, CHECK_DELAY);
67+
68+
return (): void => {
69+
clearTimeout(timer);
70+
};
71+
}, [shouldShowBottomSheet]);
72+
73+
const onMore = (): void => {
74+
navigation.navigate('Settings', { screen: 'QuickpaySettings' });
75+
dispatch(updateUser({ quickpayIntroSeen: true }));
76+
dispatch(closeSheet('quickPay'));
77+
};
78+
79+
const onDismiss = (): void => {
80+
dispatch(updateUser({ quickpayIntroSeen: true }));
81+
dispatch(closeSheet('quickPay'));
82+
};
83+
84+
return (
85+
<BottomSheetWrapper
86+
view="quickPay"
87+
snapPoints={snapPoints}
88+
onClose={(): void => {
89+
dispatch(updateUser({ quickpayIntroSeen: true }));
90+
}}>
91+
<BottomSheetScreen
92+
navTitle={t('quickpay.nav_title')}
93+
title={
94+
<Trans
95+
t={t}
96+
i18nKey="quickpay.intro.title"
97+
components={{ accent: <Display color="green" /> }}
98+
/>
99+
}
100+
description={
101+
<Trans
102+
t={t}
103+
i18nKey="quickpay.intro.description"
104+
components={{ accent: <BodyMB color="white" /> }}
105+
/>
106+
}
107+
image={imageSrc}
108+
continueText={t('learn_more')}
109+
cancelText={t('later')}
110+
testID="QuickPayPrompt"
111+
onContinue={onMore}
112+
onCancel={onDismiss}
113+
/>
114+
</BottomSheetWrapper>
115+
);
116+
};
117+
118+
export default memo(QuickPayPrompt);

src/navigation/wallet/WalletNavigator.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import ActivityFiltered from '../../screens/Activity/ActivityFiltered';
1212
import BackupPrompt from '../../screens/Settings/Backup/BackupPrompt';
1313
import AppUpdatePrompt from '../bottom-sheet/AppUpdatePrompt';
1414
import HighBalanceWarning from '../bottom-sheet/HighBalanceWarning';
15+
import QuickPayPrompt from '../bottom-sheet/QuickPayPrompt';
1516
import TabBar from '../../components/TabBar';
1617
import type { RootStackScreenProps } from '../types';
1718
import { __E2E__ } from '../../constants/env';
@@ -57,6 +58,7 @@ const WalletsStack = ({
5758
<BackupPrompt enabled={isWalletsScreenFocused} />
5859
<HighBalanceWarning enabled={isWalletsScreenFocused} />
5960
<AppUpdatePrompt enabled={isWalletsScreenFocused} />
61+
<QuickPayPrompt enabled={isWalletsScreenFocused} />
6062
</>
6163
);
6264
};

src/store/shapes/ui.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export const defaultViewControllers: TUiState['viewControllers'] = {
2020
PINNavigation: defaultViewController,
2121
profileAddDataForm: defaultViewController,
2222
pubkyAuth: defaultViewController,
23+
quickPay: defaultViewController,
2324
receiveNavigation: defaultViewController,
2425
sendNavigation: defaultViewController,
2526
timeRangePrompt: defaultViewController,

src/store/types/ui.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export type ViewControllerParamList = {
2222
PINNavigation: { showLaterButton: boolean };
2323
profileAddDataForm: undefined;
2424
pubkyAuth: { url: string };
25+
quickPay: undefined;
2526
receiveNavigation: { receiveScreen: keyof ReceiveStackParamList } | undefined;
2627
sendNavigation:
2728
| { screen: keyof SendStackParamList }

0 commit comments

Comments
 (0)