diff --git a/src/hooks/useBackgroundHandler.tsx b/src/hooks/useBackgroundHandler.tsx index f115686..38a5960 100644 --- a/src/hooks/useBackgroundHandler.tsx +++ b/src/hooks/useBackgroundHandler.tsx @@ -1,21 +1,24 @@ -import React, { MutableRefObject, useEffect } from 'react' -import { View, Text, AppState, AppStateStatus } from 'react-native' -import { KomojuProviderIprops, PaymentStatuses, TokenResponseStatuses } from '../util/types'; -import sessionShow from '../services/sessionShow'; - +import { MutableRefObject, useEffect } from "react"; +import { AppState, AppStateStatus } from "react-native"; +import { + KomojuProviderIprops, + PaymentStatuses, + TokenResponseStatuses, +} from "../util/types"; +import sessionShow from "../services/sessionShow"; type Props = { - props: KomojuProviderIprops, - startLoading: () => void - stopLoading: () => void - sessionIdRef: MutableRefObject - onCompleteCallback: MutableRefObject - onPaymentSuccess: () => void - onPaymentAwaiting: () => void - onPaymentCancelled: () => void - onSessionExpired: () => void - onPaymentFailed: () => void -} + props: KomojuProviderIprops; + startLoading: () => void; + stopLoading: () => void; + sessionIdRef: MutableRefObject; + onCompleteCallback: MutableRefObject; + onPaymentSuccess: () => void; + onPaymentAwaiting: () => void; + onPaymentCancelled: () => void; + onSessionExpired: () => void; + onPaymentFailed: () => void; +}; const useBackgroundHandler = ({ props, @@ -27,9 +30,8 @@ const useBackgroundHandler = ({ onPaymentCancelled, onPaymentFailed, onSessionExpired, - onPaymentSuccess + onPaymentSuccess, }: Props) => { - useEffect(() => { // Add event listener for deep links const windowChangeListener = AppState.addEventListener( @@ -78,7 +80,7 @@ const useBackgroundHandler = ({ sessionResponse?.status === PaymentStatuses.ERROR || sessionResponse?.payment?.status === PaymentStatuses.ERROR || sessionResponse?.secure_token?.verification_status === - TokenResponseStatuses.ERROR + TokenResponseStatuses.ERROR ) { onPaymentFailed(); } @@ -89,6 +91,6 @@ const useBackgroundHandler = ({ }; return undefined; -} +}; -export default useBackgroundHandler \ No newline at end of file +export default useBackgroundHandler; diff --git a/src/hooks/useDeepLinkHandler.tsx b/src/hooks/useDeepLinkHandler.tsx index 327ac57..8812107 100644 --- a/src/hooks/useDeepLinkHandler.tsx +++ b/src/hooks/useDeepLinkHandler.tsx @@ -1,89 +1,92 @@ -import { Linking } from 'react-native' -import { MutableRefObject, useEffect } from 'react' -import { KomojuProviderIprops, PaymentStatuses, TokenResponseStatuses } from '../util/types' -import sessionShow from '../services/sessionShow' +import { Linking } from "react-native"; +import { MutableRefObject, useEffect } from "react"; +import { + KomojuProviderIprops, + PaymentStatuses, + TokenResponseStatuses, +} from "../util/types"; +import sessionShow from "../services/sessionShow"; type Props = { - props: KomojuProviderIprops, - startLoading: () => void - stopLoading: () => void - sessionIdRef: MutableRefObject - onCompleteCallback: MutableRefObject - onPaymentSuccess: () => void - onPaymentAwaiting: () => void - onPaymentCancelled: () => void - onPaymentFailed: () => void -} + props: KomojuProviderIprops; + startLoading: () => void; + stopLoading: () => void; + sessionIdRef: MutableRefObject; + onCompleteCallback: MutableRefObject; + onPaymentSuccess: () => void; + onPaymentAwaiting: () => void; + onPaymentCancelled: () => void; + onPaymentFailed: () => void; +}; const useDeepLinkHandler = ({ - props, - startLoading, - stopLoading, - sessionIdRef, - onCompleteCallback, - onPaymentAwaiting, - onPaymentCancelled, - onPaymentFailed, - onPaymentSuccess + props, + startLoading, + stopLoading, + sessionIdRef, + onCompleteCallback, + onPaymentAwaiting, + onPaymentCancelled, + onPaymentFailed, + onPaymentSuccess, }: Props) => { + useEffect(() => { + // Add event listener for deep links + const subscription = Linking.addEventListener( + "url", + handleDeepLinkStateChange + ); - useEffect(() => { - // Add event listener for deep links - const subscription = Linking.addEventListener( - 'url', - handleDeepLinkStateChange - ); - - return () => { - subscription.remove(); - }; - }, [props]); + return () => { + subscription.remove(); + }; + }, [props]); - const handleDeepLinkStateChange = async () => { - startLoading(); + const handleDeepLinkStateChange = async () => { + startLoading(); - // if this is a session flow, check until session response changes from 'pending' to 'completed' or 'error' - const sessionShowPayload = { - publishableKey: props.publishableKey, - sessionId: sessionIdRef.current, - }; + // if this is a session flow, check until session response changes from 'pending' to 'completed' or 'error' + const sessionShowPayload = { + publishableKey: props.publishableKey, + sessionId: sessionIdRef.current, + }; - // fetch session status to check if the payment is completed - let sessionResponse = await sessionShow(sessionShowPayload); + // fetch session status to check if the payment is completed + let sessionResponse = await sessionShow(sessionShowPayload); - // Polling until session verification status changes - while ( - sessionResponse?.status === PaymentStatuses.PENDING && - sessionResponse?.payment?.status !== PaymentStatuses.CANCELLED && - sessionResponse?.secure_token?.verification_status !== - TokenResponseStatuses.ERROR - ) { - sessionResponse = await sessionShow(sessionShowPayload); - } + // Polling until session verification status changes + while ( + sessionResponse?.status === PaymentStatuses.PENDING && + sessionResponse?.payment?.status !== PaymentStatuses.CANCELLED && + sessionResponse?.secure_token?.verification_status !== + TokenResponseStatuses.ERROR + ) { + sessionResponse = await sessionShow(sessionShowPayload); + } - // if payment success showing success screen or if failed showing error screen - if (sessionResponse?.status === PaymentStatuses.SUCCESS) { - if (sessionResponse?.payment?.status === TokenResponseStatuses.CAPTURED) { - onPaymentSuccess(); - } else { - onPaymentAwaiting(); - } - // calling user passed onComplete method with session response data - onCompleteCallback.current && - // TODO: Fix this type error - // @ts-expect-error - Argument of type 'PaymentSessionResponse' is not assignable to parameter of type 'string'. - onCompleteCallback.current(sessionResponse); - } else if (sessionResponse?.payment?.status === PaymentStatuses.CANCELLED) { - onPaymentCancelled(); - } else { - onPaymentFailed(); - } + // if payment success showing success screen or if failed showing error screen + if (sessionResponse?.status === PaymentStatuses.SUCCESS) { + if (sessionResponse?.payment?.status === TokenResponseStatuses.CAPTURED) { + onPaymentSuccess(); + } else { + onPaymentAwaiting(); + } + // calling user passed onComplete method with session response data + onCompleteCallback.current && + // TODO: Fix this type error + // @ts-expect-error - Argument of type 'PaymentSessionResponse' is not assignable to parameter of type 'string'. + onCompleteCallback.current(sessionResponse); + } else if (sessionResponse?.payment?.status === PaymentStatuses.CANCELLED) { + onPaymentCancelled(); + } else { + onPaymentFailed(); + } - // after all api calls are done stopping the loading indicator - stopLoading(); - }; + // after all api calls are done stopping the loading indicator + stopLoading(); + }; - return undefined; -} + return undefined; +}; -export default useDeepLinkHandler \ No newline at end of file +export default useDeepLinkHandler; diff --git a/src/hooks/useMainStateUtils.tsx b/src/hooks/useMainStateUtils.tsx index c01457c..777fabd 100644 --- a/src/hooks/useMainStateUtils.tsx +++ b/src/hooks/useMainStateUtils.tsx @@ -1,134 +1,137 @@ -import { MutableRefObject, RefObject, useContext } from 'react' +import { MutableRefObject, RefObject, useContext } from "react"; -import { Actions, DispatchContext } from '../context/state'; -import { SheetRefProps } from '../components/Sheet'; -import { KomojuProviderIprops, ResponseScreenStatuses, State } from '../util/types'; -import sessionShow from '../services/sessionShow'; +import { Actions, DispatchContext } from "../context/state"; +import { SheetRefProps } from "../components/Sheet"; +import { + KomojuProviderIprops, + ResponseScreenStatuses, + State, +} from "../util/types"; +import sessionShow from "../services/sessionShow"; type Props = { - props: KomojuProviderIprops, - sheetRef: RefObject, - sessionIdRef: MutableRefObject - toggleUIVisibility: (value: boolean) => void, - initialState: State, - onDismissCallback: MutableRefObject, -} + props: KomojuProviderIprops; + sheetRef: RefObject; + sessionIdRef: MutableRefObject; + toggleUIVisibility: (value: boolean) => void; + initialState: State; + onDismissCallback: MutableRefObject; +}; const useMainStateUtils = ({ - props, - sheetRef, - sessionIdRef, - toggleUIVisibility, - initialState, - onDismissCallback - + props, + sheetRef, + sessionIdRef, + toggleUIVisibility, + initialState, + onDismissCallback, }: Props) => { - const dispatch = useContext(DispatchContext); - const openPaymentSheet = () => { - if (props?.useBottomSheet) { - sheetRef?.current?.open(); - } else { - toggleUIVisibility(true); - } - }; - - const closePaymentSheet = () => { - // TODO: Fix this type error - // @ts-expect-error - Object is possibly 'null'. - sheetRef?.current?.close(false); - toggleUIVisibility(false); - }; - - const resetGlobalStates = () => - dispatch({ - type: Actions.RESET_STATES, - payload: initialState, - }); - - // when payment is success global state is rest and invoking the success screen - const onPaymentSuccess = () => { - resetGlobalStates(); - dispatch({ - type: Actions.SET_PAYMENT_STATE, - payload: ResponseScreenStatuses.SUCCESS, - }); - }; - - // when payment is failed invoking the error screen - const onPaymentFailed = () => - dispatch({ - type: Actions.SET_PAYMENT_STATE, - payload: ResponseScreenStatuses.FAILED, - }); - - // when payment is cancelled by the user - const onPaymentCancelled = () => { - resetGlobalStates(); - dispatch({ - type: Actions.SET_PAYMENT_STATE, - payload: ResponseScreenStatuses.CANCELLED, - }); - }; - - // when payment is completed but awaiting payment - const onPaymentAwaiting = () => { - resetGlobalStates(); - dispatch({ - type: Actions.SET_PAYMENT_STATE, - payload: ResponseScreenStatuses.COMPLETE, - }); - }; - - // when payment is failed invoking the error screen - const onSessionExpired = () => - dispatch({ - type: Actions.SET_PAYMENT_STATE, - payload: ResponseScreenStatuses.EXPIRED, - }); - - const onUserCancel = async () => { - if (onDismissCallback.current) { - const sessionShowPayload = { - publishableKey: props?.publishableKey, - sessionId: sessionIdRef.current, - }; - - // fetch session status to check if the payment is completed - const sessionResponse = await sessionShow(sessionShowPayload); - // invoking client provided onDismiss callback - // TODO: Fix this type error - // @ts-expect-error - Argument of type 'PaymentSessionResponse' is not assignable to parameter of type 'string'. - onDismissCallback.current(sessionResponse); - } - }; - - // showing overlay loading indicator disabling all interactions - const startLoading = () => - dispatch({ - type: Actions.SET_LOADING, - payload: true, - }); - - // Hiding overlay loading indicator - const stopLoading = () => - dispatch({ - type: Actions.SET_LOADING, - payload: false, - }); - - return { - openPaymentSheet, - closePaymentSheet, - onPaymentSuccess, - onPaymentFailed, - onPaymentCancelled, - onPaymentAwaiting, - onSessionExpired, - onUserCancel, - startLoading, - stopLoading, - resetGlobalStates + const dispatch = useContext(DispatchContext); + const openPaymentSheet = () => { + if (props?.useBottomSheet) { + sheetRef?.current?.open(); + } else { + toggleUIVisibility(true); } -} - -export default useMainStateUtils \ No newline at end of file + }; + + const closePaymentSheet = () => { + // TODO: Fix this type error + // @ts-expect-error - Object is possibly 'null'. + sheetRef?.current?.close(false); + toggleUIVisibility(false); + }; + + const resetGlobalStates = () => + dispatch({ + type: Actions.RESET_STATES, + payload: initialState, + }); + + // when payment is success global state is rest and invoking the success screen + const onPaymentSuccess = () => { + resetGlobalStates(); + dispatch({ + type: Actions.SET_PAYMENT_STATE, + payload: ResponseScreenStatuses.SUCCESS, + }); + }; + + // when payment is failed invoking the error screen + const onPaymentFailed = () => + dispatch({ + type: Actions.SET_PAYMENT_STATE, + payload: ResponseScreenStatuses.FAILED, + }); + + // when payment is cancelled by the user + const onPaymentCancelled = () => { + resetGlobalStates(); + dispatch({ + type: Actions.SET_PAYMENT_STATE, + payload: ResponseScreenStatuses.CANCELLED, + }); + }; + + // when payment is completed but awaiting payment + const onPaymentAwaiting = () => { + resetGlobalStates(); + dispatch({ + type: Actions.SET_PAYMENT_STATE, + payload: ResponseScreenStatuses.COMPLETE, + }); + }; + + // when payment is failed invoking the error screen + const onSessionExpired = () => + dispatch({ + type: Actions.SET_PAYMENT_STATE, + payload: ResponseScreenStatuses.EXPIRED, + }); + + const onUserCancel = async () => { + if (onDismissCallback.current) { + const sessionShowPayload = { + publishableKey: props?.publishableKey, + sessionId: sessionIdRef.current, + }; + + // fetch session status to check if the payment is completed + const sessionResponse = await sessionShow(sessionShowPayload); + // invoking client provided onDismiss callback + // TODO: Fix this type error + // @ts-expect-error - Argument of type 'PaymentSessionResponse' is not assignable to parameter of type 'string'. + onDismissCallback.current(sessionResponse); + } + }; + + // showing overlay loading indicator disabling all interactions + const startLoading = () => + dispatch({ + type: Actions.SET_LOADING, + payload: true, + }); + + // Hiding overlay loading indicator + const stopLoading = () => + dispatch({ + type: Actions.SET_LOADING, + payload: false, + }); + + return { + openPaymentSheet, + closePaymentSheet, + onPaymentSuccess, + onPaymentFailed, + onPaymentCancelled, + onPaymentAwaiting, + onSessionExpired, + onUserCancel, + startLoading, + stopLoading, + resetGlobalStates, + }; +}; + +export default useMainStateUtils;