From 5fe82857323ac8cbf85322a722c860e79fbcbba7 Mon Sep 17 00:00:00 2001 From: Philipp Walter Date: Thu, 12 Dec 2024 13:37:51 +0100 Subject: [PATCH] feat(ui): add QuickPay prompt --- .../bottom-sheet/QuickPayPrompt.tsx | 118 ++++++++++++++++++ src/navigation/wallet/WalletNavigator.tsx | 2 + src/store/shapes/ui.ts | 1 + src/store/types/ui.ts | 1 + 4 files changed, 122 insertions(+) create mode 100644 src/navigation/bottom-sheet/QuickPayPrompt.tsx diff --git a/src/navigation/bottom-sheet/QuickPayPrompt.tsx b/src/navigation/bottom-sheet/QuickPayPrompt.tsx new file mode 100644 index 000000000..90933bb99 --- /dev/null +++ b/src/navigation/bottom-sheet/QuickPayPrompt.tsx @@ -0,0 +1,118 @@ +import React, { memo, ReactElement, useEffect, useMemo } from 'react'; +import { useNavigation } from '@react-navigation/native'; +import { Trans, useTranslation } from 'react-i18next'; + +import { __E2E__ } from '../../constants/env'; +import { BodyMB, Display } from '../../styles/text'; +import BottomSheetWrapper from '../../components/BottomSheetWrapper'; +import BottomSheetScreen from '../../components/BottomSheetScreen'; +import { objectKeys } from '../../utils/objectKeys'; +import { useBalance } from '../../hooks/wallet'; +import { useAppDispatch, useAppSelector } from '../../hooks/redux'; +import { + useBottomSheetBackPress, + useSnapPoints, +} from '../../hooks/bottomSheet'; +import { closeSheet } from '../../store/slices/ui'; +import { updateUser } from '../../store/slices/user'; +import { showBottomSheet } from '../../store/utils/ui'; +import { viewControllersSelector } from '../../store/reselect/ui'; +import { quickpayIntroSeenSelector } from '../../store/reselect/user'; +import { RootNavigationProp } from '../types'; + +const imageSrc = require('../../assets/illustrations/fast-forward.png'); + +const CHECK_DELAY = 3000; // how long user needs to stay on Wallets screen before he will see this prompt + +const QuickPayPrompt = ({ enabled }: { enabled: boolean }): ReactElement => { + const { t } = useTranslation('settings'); + const navigation = useNavigation(); + const { spendingBalance } = useBalance(); + const snapPoints = useSnapPoints('large'); + const dispatch = useAppDispatch(); + const viewControllers = useAppSelector(viewControllersSelector); + const quickpayIntroSeen = useAppSelector(quickpayIntroSeenSelector); + + useBottomSheetBackPress('quickPay'); + + const anyBottomSheetIsOpen = useMemo(() => { + const viewControllerKeys = objectKeys(viewControllers); + return viewControllerKeys + .filter((view) => view !== 'quickPay') + .some((view) => viewControllers[view].isOpen); + }, [viewControllers]); + + // if user hasn't seen this prompt + // and has a spending balance + // and no other bottom-sheets are shown + // and user on "Wallets" screen for CHECK_DELAY + const shouldShowBottomSheet = useMemo(() => { + return ( + enabled && + !__E2E__ && + !anyBottomSheetIsOpen && + !quickpayIntroSeen && + spendingBalance > 0 + ); + }, [enabled, anyBottomSheetIsOpen, quickpayIntroSeen, spendingBalance]); + + useEffect(() => { + if (!shouldShowBottomSheet) { + return; + } + + const timer = setTimeout(() => { + showBottomSheet('quickPay'); + }, CHECK_DELAY); + + return (): void => { + clearTimeout(timer); + }; + }, [shouldShowBottomSheet]); + + const onMore = (): void => { + navigation.navigate('Settings', { screen: 'QuickpaySettings' }); + dispatch(updateUser({ quickpayIntroSeen: true })); + dispatch(closeSheet('quickPay')); + }; + + const onDismiss = (): void => { + dispatch(updateUser({ quickpayIntroSeen: true })); + dispatch(closeSheet('quickPay')); + }; + + return ( + { + dispatch(updateUser({ quickpayIntroSeen: true })); + }}> + }} + /> + } + description={ + }} + /> + } + image={imageSrc} + continueText={t('learn_more')} + cancelText={t('later')} + testID="QuickPayPrompt" + onContinue={onMore} + onCancel={onDismiss} + /> + + ); +}; + +export default memo(QuickPayPrompt); diff --git a/src/navigation/wallet/WalletNavigator.tsx b/src/navigation/wallet/WalletNavigator.tsx index d0873cc60..6854d616c 100644 --- a/src/navigation/wallet/WalletNavigator.tsx +++ b/src/navigation/wallet/WalletNavigator.tsx @@ -12,6 +12,7 @@ import ActivityFiltered from '../../screens/Activity/ActivityFiltered'; import BackupPrompt from '../../screens/Settings/Backup/BackupPrompt'; import AppUpdatePrompt from '../bottom-sheet/AppUpdatePrompt'; import HighBalanceWarning from '../bottom-sheet/HighBalanceWarning'; +import QuickPayPrompt from '../bottom-sheet/QuickPayPrompt'; import TabBar from '../../components/TabBar'; import type { RootStackScreenProps } from '../types'; import { __E2E__ } from '../../constants/env'; @@ -57,6 +58,7 @@ const WalletsStack = ({ + ); }; diff --git a/src/store/shapes/ui.ts b/src/store/shapes/ui.ts index 8f1a94f9a..d44bd4c78 100644 --- a/src/store/shapes/ui.ts +++ b/src/store/shapes/ui.ts @@ -20,6 +20,7 @@ export const defaultViewControllers: TUiState['viewControllers'] = { PINNavigation: defaultViewController, profileAddDataForm: defaultViewController, pubkyAuth: defaultViewController, + quickPay: defaultViewController, receiveNavigation: defaultViewController, sendNavigation: defaultViewController, timeRangePrompt: defaultViewController, diff --git a/src/store/types/ui.ts b/src/store/types/ui.ts index 21deadd57..0d923276c 100644 --- a/src/store/types/ui.ts +++ b/src/store/types/ui.ts @@ -22,6 +22,7 @@ export type ViewControllerParamList = { PINNavigation: { showLaterButton: boolean }; profileAddDataForm: undefined; pubkyAuth: { url: string }; + quickPay: undefined; receiveNavigation: { receiveScreen: keyof ReceiveStackParamList } | undefined; sendNavigation: | { screen: keyof SendStackParamList }