diff --git a/app/assets/animations/Error Pulse Loop.json b/app/assets/animations/error_pulse_loop.json similarity index 100% rename from app/assets/animations/Error Pulse Loop.json rename to app/assets/animations/error_pulse_loop.json diff --git a/app/assets/animations/Lightning Pulse Loop.json b/app/assets/animations/lightning_pulse_loop.json similarity index 100% rename from app/assets/animations/Lightning Pulse Loop.json rename to app/assets/animations/lightning_pulse_loop.json diff --git a/app/assets/animations/Lightning Success.json b/app/assets/animations/lightning_success.json similarity index 100% rename from app/assets/animations/Lightning Success.json rename to app/assets/animations/lightning_success.json diff --git a/app/assets/animations/On Chain Pulse Loop.json b/app/assets/animations/onchain_pulse_loop.json similarity index 100% rename from app/assets/animations/On Chain Pulse Loop.json rename to app/assets/animations/onchain_pulse_loop.json diff --git a/app/assets/animations/On Chain Success.json b/app/assets/animations/onchain_success.json similarity index 100% rename from app/assets/animations/On Chain Success.json rename to app/assets/animations/onchain_success.json diff --git a/app/assets/animations/Sending Loop.json b/app/assets/animations/send_loop.json similarity index 100% rename from app/assets/animations/Sending Loop.json rename to app/assets/animations/send_loop.json diff --git a/app/assets/animations/Sending Start.json b/app/assets/animations/send_start.json similarity index 100% rename from app/assets/animations/Sending Start.json rename to app/assets/animations/send_start.json diff --git a/app/assets/animations/Sending Transition.json b/app/assets/animations/send_transition.json similarity index 100% rename from app/assets/animations/Sending Transition.json rename to app/assets/animations/send_transition.json diff --git a/app/navigation/stack-param-lists.ts b/app/navigation/stack-param-lists.ts index d7d3ba74d1..b8dbd11f22 100644 --- a/app/navigation/stack-param-lists.ts +++ b/app/navigation/stack-param-lists.ts @@ -6,10 +6,7 @@ import { ReceiveDestination, } from "@app/screens/send-bitcoin-screen/payment-destination/index.types" import { PaymentDetail } from "@app/screens/send-bitcoin-screen/payment-details/index.types" -import { - PaymentSendCompletedStatus, - SendPayment, -} from "@app/screens/send-bitcoin-screen/use-send-payment" +import { PaymentSendCompletedStatus } from "@app/screens/send-bitcoin-screen/use-send-payment" import { DisplayCurrency, MoneyAmount, WalletOrDisplayCurrency } from "@app/types/amounts" import { WalletDescriptor } from "@app/types/wallets" import { NavigatorScreenParams } from "@react-navigation/native" @@ -40,17 +37,15 @@ export type RootStackParamList = { payment?: string username?: string } - sendBitcoinPayment: { - sendPayment: SendPayment - paymentDetail: PaymentDetail - sendingWallet: WalletCurrency - } sendBitcoinDetails: { paymentDestination: PaymentDestination } sendBitcoinConfirmation: { paymentDetail: PaymentDetail } + sendBitcoinPayment: { + paymentDetail: PaymentDetail + } conversionDetails: undefined conversionConfirmation: { fromWalletCurrency: WalletCurrency diff --git a/app/screens/send-bitcoin-screen/send-bitcoin-confirmation-screen.tsx b/app/screens/send-bitcoin-screen/send-bitcoin-confirmation-screen.tsx index c84ce9445d..3b19446189 100644 --- a/app/screens/send-bitcoin-screen/send-bitcoin-confirmation-screen.tsx +++ b/app/screens/send-bitcoin-screen/send-bitcoin-confirmation-screen.tsx @@ -30,14 +30,12 @@ import { import { logPaymentAttempt } from "@app/utils/analytics" import { toastShow } from "@app/utils/toast" import Clipboard from "@react-native-clipboard/clipboard" -import crashlytics from "@react-native-firebase/crashlytics" import { RouteProp, useNavigation } from "@react-navigation/native" import { StackNavigationProp } from "@react-navigation/stack" import { makeStyles, Text, useTheme } from "@rneui/themed" import { testProps } from "../../utils/testProps" import useFee from "./use-fee" -import { useSendPayment } from "./use-send-payment" gql` query sendBitcoinConfirmationScreen { @@ -74,7 +72,6 @@ const SendBitcoinConfirmationScreen: React.FC = ({ route }) => { destination, paymentType, sendingWalletDescriptor, - sendPaymentMutation, getFee, settlementAmount, memo: note, @@ -83,6 +80,8 @@ const SendBitcoinConfirmationScreen: React.FC = ({ route }) => { isSendingMax, } = paymentDetail + const [sliderSlid, setSliderSlid] = useState(false) + const { formatDisplayAndWalletAmount } = useDisplayCurrency() const { data } = useSendBitcoinConfirmationScreenQuery({ skip: !useIsAuthed() }) @@ -109,12 +108,6 @@ const SendBitcoinConfirmationScreen: React.FC = ({ route }) => { const fee = useFee(getFee) - const { - loading: sendPaymentLoading, - sendPayment, - hasAttemptedSend, - } = useSendPayment(sendPaymentMutation) - let feeDisplayText = "" if (fee.amount) { const feeDisplayAmount = paymentDetail.convertMoneyAmount(fee.amount, DisplayCurrency) @@ -127,84 +120,29 @@ const SendBitcoinConfirmationScreen: React.FC = ({ route }) => { } const handleSendPayment = React.useCallback(async () => { - if (!sendPayment || !sendingWalletDescriptor?.currency) { - return sendPayment + if (sliderSlid || !sendingWalletDescriptor?.currency) { + return } - try { - logPaymentAttempt({ - paymentType: paymentDetail.paymentType, - sendingWallet: sendingWalletDescriptor.currency, - }) + logPaymentAttempt({ + paymentType: paymentDetail.paymentType, + sendingWallet: sendingWalletDescriptor.currency, + }) - navigation.reset({ - routes: [ - { name: "Primary" }, - { - name: "sendBitcoinPayment", - params: { - sendPayment, - paymentDetail, - sendingWallet: sendingWalletDescriptor.currency, - }, + navigation.reset({ + routes: [ + { name: "Primary" }, + { + name: "sendBitcoinPayment", + params: { + paymentDetail, }, - ], - }) + }, + ], + }) - // const { status, errorsMessage, extraInfo } = await sendPayment() - - // if (status === "SUCCESS" || status === "PENDING") { - // navigation.dispatch((state) => { - // const routes = [ - // { name: "Primary" }, - // { - // name: "sendBitcoinCompleted", - // params: { - // arrivalAtMempoolEstimate: extraInfo?.arrivalAtMempoolEstimate, - // status, - // }, - // }, - // ] - // return CommonActions.reset({ - // ...state, - // routes, - // index: routes.length - 1, - // }) - // }) - // ReactNativeHapticFeedback.trigger("notificationSuccess", { - // ignoreAndroidSystemSettings: true, - // }) - // return - // } - - // if (status === "ALREADY_PAID") { - // setPaymentError(LL.SendBitcoinConfirmationScreen.invoiceAlreadyPaid()) - // ReactNativeHapticFeedback.trigger("notificationError", { - // ignoreAndroidSystemSettings: true, - // }) - // return - // } - - // setPaymentError( - // errorsMessage || LL.SendBitcoinConfirmationScreen.somethingWentWrong(), - // ) - // ReactNativeHapticFeedback.trigger("notificationError", { - // ignoreAndroidSystemSettings: true, - // }) - } catch (err) { - if (err instanceof Error) { - crashlytics().recordError(err) - - // const indempotencyErrorPattern = /409: Conflict/i - // if (indempotencyErrorPattern.test(err.message)) { - // setPaymentError(LL.SendBitcoinConfirmationScreen.paymentAlreadyAttempted()) - // return - // } - - // setPaymentError(err.message || err.toString()) - } - } - }, [navigation, paymentDetail, sendPayment, sendingWalletDescriptor.currency]) + setSliderSlid(true) + }, [sliderSlid, sendingWalletDescriptor.currency, paymentDetail, navigation]) let validAmount = true let invalidAmountErrorMessage = "" @@ -425,11 +363,11 @@ const SendBitcoinConfirmationScreen: React.FC = ({ route }) => { ) : null} diff --git a/app/screens/send-bitcoin-screen/send-bitcoin-payment-screen.tsx b/app/screens/send-bitcoin-screen/send-bitcoin-payment-screen.tsx index 881d49a2ec..b827e2000f 100644 --- a/app/screens/send-bitcoin-screen/send-bitcoin-payment-screen.tsx +++ b/app/screens/send-bitcoin-screen/send-bitcoin-payment-screen.tsx @@ -3,15 +3,15 @@ import React, { useEffect, useRef, useState } from "react" import { Animated, BackHandler, Dimensions, Easing, View } from "react-native" import ReactNativeHapticFeedback from "react-native-haptic-feedback" -import erroredLoop from "@app/assets/animations/Error Pulse Loop.json" -import errored from "@app/assets/animations/Error.json" -import lnSuccessLoop from "@app/assets/animations/Lightning Pulse Loop.json" -import lnSuccess from "@app/assets/animations/Lightning Success.json" -import onchainSuccessLoop from "@app/assets/animations/On Chain Pulse Loop.json" -import onchainSuccess from "@app/assets/animations/On Chain Success.json" -import sendingLoop from "@app/assets/animations/Sending Loop.json" -import sendingStart from "@app/assets/animations/Sending Start.json" -import sendingTransition from "@app/assets/animations/Sending Transition.json" +import errored from "@app/assets/animations/error.json" +import erroredLoop from "@app/assets/animations/error_pulse_loop.json" +import lnSuccessLoop from "@app/assets/animations/lightning_pulse_loop.json" +import lnSuccess from "@app/assets/animations/lightning_success.json" +import onchainSuccessLoop from "@app/assets/animations/onchain_pulse_loop.json" +import onchainSuccess from "@app/assets/animations/onchain_success.json" +import sendingLoop from "@app/assets/animations/send_loop.json" +import sendingStart from "@app/assets/animations/send_start.json" +import sendingTransition from "@app/assets/animations/send_transition.json" import LogoDarkMode from "@app/assets/logo/app-logo-dark.svg" import LogoLightMode from "@app/assets/logo/blink-logo-light.svg" import { GaloyPrimaryButton } from "@app/components/atomic/galoy-primary-button" @@ -21,6 +21,7 @@ import { useDisplayCurrency } from "@app/hooks/use-display-currency" import { useI18nContext } from "@app/i18n/i18n-react" import { RootStackParamList } from "@app/navigation/stack-param-lists" import { logPaymentResult } from "@app/utils/analytics" +import crashlytics from "@react-native-firebase/crashlytics" import { RouteProp, useNavigation } from "@react-navigation/native" import { StackNavigationProp } from "@react-navigation/stack" import { Text, makeStyles, useTheme } from "@rneui/themed" @@ -29,7 +30,11 @@ import { formatTimeToMempool, timeToMempool, } from "../transaction-detail-screen/format-time" -import { SendPayment, PaymentSendCompletedStatus } from "./use-send-payment" +import { + SendPayment, + PaymentSendCompletedStatus, + useSendPayment, +} from "./use-send-payment" const animationMap = { START: sendingStart, @@ -53,6 +58,9 @@ const calculateDuration = (frameCount: number) => (frameCount / 30) * 1000 const SendBitcoinPaymentScreen: React.FC = ({ route }) => { const { LL, locale } = useI18nContext() + const { paymentDetail } = route.params + const { sendPayment } = useSendPayment(paymentDetail.sendPaymentMutation) + const { theme: { mode }, } = useTheme() @@ -71,16 +79,38 @@ const SendBitcoinPaymentScreen: React.FC = ({ route }) => { > | null>(null) useEffect(() => { + if (!sendPayment) return ;(async () => { - const data = await route.params.sendPayment() - setPaymentResult(data) - logPaymentResult({ - paymentStatus: data.status, - paymentType: route.params.paymentDetail.paymentType, - sendingWallet: route.params.sendingWallet, - }) + try { + const data = await sendPayment() + setPaymentResult(data) + logPaymentResult({ + paymentStatus: data.status, + paymentType: route.params.paymentDetail.paymentType, + sendingWallet: route.params.paymentDetail.sendingWalletDescriptor.currency, + }) + } catch (err) { + if (err instanceof Error) { + crashlytics().recordError(err) + + const indempotencyErrorPattern = /409: Conflict/i + if (indempotencyErrorPattern.test(err.message)) { + return setPaymentResult({ + status: "ALREADY_PAID", + errorsMessage: LL.SendBitcoinConfirmationScreen.paymentAlreadyAttempted(), + transaction: null, + }) + } + + return setPaymentResult({ + status: "FAILURE", + errorsMessage: err.message, + transaction: null, + }) + } + } })() - }, [route.params]) + }, [LL.SendBitcoinConfirmationScreen, route.params, sendPayment]) const fadeAnim = useRef(new Animated.Value(0)).current