import { NativeStackScreenProps } from '@react-navigation/native-stack' import BigNumber from 'bignumber.js' import React, { useMemo, useRef, useState } from 'react' import { useAsyncCallback } from 'react-async-hook' import { useTranslation } from 'react-i18next' import { Share, StyleSheet, Text, View } from 'react-native' import { ScrollView } from 'react-native-gesture-handler' import QRCode from 'react-native-qrcode-svg' import { SafeAreaView, useSafeAreaInsets } from 'react-native-safe-area-context' import AppAnalytics from 'src/analytics/AppAnalytics' import { JumpstartEvents } from 'src/analytics/Events' import { JumpstartShareOrigin } from 'src/analytics/Properties' import BottomSheet, { BottomSheetModalRefType } from 'src/components/BottomSheet' import Button, { BtnSizes } from 'src/components/Button' import DataFieldWithCopy from 'src/components/DataFieldWithCopy' import Dialog from 'src/components/Dialog' import CustomHeader from 'src/components/header/CustomHeader' import QRCodeIcon from 'src/icons/QRCode' import ShareIcon from 'src/icons/Share' import Times from 'src/icons/Times' import { noHeaderGestureDisabled } from 'src/navigator/Headers' import { navigateHome } from 'src/navigator/NavigationService' import { Screens } from 'src/navigator/Screens' import { TopBarIconButton } from 'src/navigator/TopBarButton' import { StackParamList } from 'src/navigator/types' import { typeScale } from 'src/styles/fonts' import { Spacing } from 'src/styles/styles' import { useTokenInfo } from 'src/tokens/hooks' import Logger from 'src/utils/Logger' import { ensureError } from 'src/utils/ensureError' import useBackHandler from 'src/utils/useBackHandler' type Props = NativeStackScreenProps const TAG = 'JumpstartShareLink' function JumpstartShareLink({ route }: Props) { const { tokenId, link, sendAmount } = route.params const { t } = useTranslation() const insets = useSafeAreaInsets() const qrCodeBottomSheetRef = useRef(null) const shouldNavigate = useRef(false) const [showNavigationWarning, setShowNavigationWarning] = useState(false) const token = useTokenInfo(tokenId) const trackedDepositProperties = useMemo(() => { return { tokenId, networkId: token?.networkId || null, amountInUsd: new BigNumber(sendAmount).multipliedBy(token?.priceUsd || 0).toString(), } }, [token, route.params]) useBackHandler(() => { if (!showNavigationWarning) { handleShowNavigationWarning() } return true }, []) const nativeShare = useAsyncCallback( async (origin: JumpstartShareOrigin) => { AppAnalytics.track(JumpstartEvents.jumpstart_share_link, { ...trackedDepositProperties, origin, }) qrCodeBottomSheetRef.current?.close() const result = await Share.share({ message: t('jumpstartShareLinkScreen.shareMessage', { link, tokenAmount: sendAmount, tokenSymbol: token?.symbol, }), }) return result }, { onSuccess: (result) => { AppAnalytics.track(JumpstartEvents.jumpstart_share_link_result, { ...result, ...trackedDepositProperties, }) }, onError: (error) => { AppAnalytics.track(JumpstartEvents.jumpstart_share_link_result, { ...trackedDepositProperties, error: ensureError(error).message, }) }, } ) const handleShowNavigationWarning = () => { AppAnalytics.track(JumpstartEvents.jumpstart_share_close) setShowNavigationWarning(true) } const handleConfirmNavigation = () => { AppAnalytics.track(JumpstartEvents.jumpstart_share_confirm_close) // calling navigateHome directly from this function causes an app crash, // possibly because of the race condition between navigation and unmounting // the Dialog (Modal). Using a ref to track the user's intention to navigate // as a quick fix here, as we plan to remove the use of the Dialog soon. setShowNavigationWarning(false) shouldNavigate.current = true } const handleDismissNavigationWarning = () => { AppAnalytics.track(JumpstartEvents.jumpstart_share_dismiss_close) setShowNavigationWarning(false) } const handleNavigation = () => { if (shouldNavigate.current) { navigateHome() } } const handleShowQRBottomSheet = () => { AppAnalytics.track(JumpstartEvents.jumpstart_show_QR, trackedDepositProperties) qrCodeBottomSheetRef.current?.snapToIndex(0) } const handleCopyLink = (origin: JumpstartShareOrigin) => () => { AppAnalytics.track(JumpstartEvents.jumpstart_copy_link, { ...trackedDepositProperties, origin, }) } if (!token) { // should never happen Logger.error(TAG, 'Token is undefined') return null } return ( } onPress={handleShowNavigationWarning} testID="JumpstartShareLink/CloseButton" /> } /> {t('jumpstartShareLinkScreen.title')} {t('jumpstartShareLinkScreen.description', { tokenSymbol: token.symbol })}