diff --git a/src/eventEmitter.ts b/src/eventEmitter.ts new file mode 100644 index 000000000..71e1d2430 --- /dev/null +++ b/src/eventEmitter.ts @@ -0,0 +1,49 @@ +import {EmitterSubscription, NativeEventEmitter} from 'react-native'; + +import {getAndroidModule, getIosModule, getNativeModule} from './iap'; +import {isAndroid, isIos} from './internal'; +import type {PurchaseError} from './purchaseError'; +import type {Purchase} from './types'; + +const eventEmitter = new NativeEventEmitter(getNativeModule()); + +/** + * Add IAP purchase event + */ +export const purchaseUpdatedListener = ( + listener: (event: Purchase) => void, +) => { + const emitterSubscription = eventEmitter.addListener( + 'purchase-updated', + listener, + ); + + if (isAndroid) { + getAndroidModule().startListening(); + } + + return emitterSubscription; +}; + +/** + * Add IAP purchase error event + */ +export const purchaseErrorListener = ( + listener: (error: PurchaseError) => void, +): EmitterSubscription => eventEmitter.addListener('purchase-error', listener); + +/** + * Add IAP promoted subscription event + * + * @platform iOS + */ +export const promotedProductListener = (listener: () => void) => { + if (isIos) { + return new NativeEventEmitter(getIosModule()).addListener( + 'iap-promoted-product', + listener, + ); + } + + return null; +}; diff --git a/src/hooks/withIAPContext.tsx b/src/hooks/withIAPContext.tsx index 7d5c6c73b..9b6c95a61 100644 --- a/src/hooks/withIAPContext.tsx +++ b/src/hooks/withIAPContext.tsx @@ -1,12 +1,11 @@ import React, {useContext, useEffect, useMemo, useState} from 'react'; import { - getPromotedProductIOS, - initConnection, promotedProductListener, purchaseErrorListener, purchaseUpdatedListener, -} from '../iap'; +} from '../eventEmitter'; +import {getPromotedProductIOS, initConnection} from '../iap'; import type {PurchaseError} from '../purchaseError'; import type { InAppPurchase, diff --git a/src/iap.ts b/src/iap.ts index b5a3e1ad8..982e22ed2 100644 --- a/src/iap.ts +++ b/src/iap.ts @@ -1,10 +1,4 @@ -import { - EmitterSubscription, - Linking, - NativeEventEmitter, - NativeModules, - Platform, -} from 'react-native'; +import {Linking, NativeModules, Platform} from 'react-native'; import type * as Amazon from './types/amazon'; import type * as Android from './types/android'; @@ -15,9 +9,7 @@ import { fillProductsWithAdditionalData, isAmazon, isAndroid, - isIos, } from './internal'; -import type {PurchaseError} from './purchaseError'; import type { InAppPurchase, Product, @@ -55,7 +47,9 @@ const checkNativeAndroidAvailable = (): void => { } }; -const getAndroidModule = (): typeof RNIapModule | typeof RNIapAmazonModule => { +export const getAndroidModule = (): + | typeof RNIapModule + | typeof RNIapAmazonModule => { checkNativeAndroidAvailable(); return androidNativeModule @@ -71,13 +65,13 @@ const checkNativeIOSAvailable = (): void => { } }; -const getIosModule = (): typeof RNIapIos => { +export const getIosModule = (): typeof RNIapIos => { checkNativeIOSAvailable(); return RNIapIos; }; -const getNativeModule = (): +export const getNativeModule = (): | typeof RNIapModule | typeof RNIapAmazonModule | typeof RNIapIos => { @@ -575,52 +569,6 @@ export const validateReceiptAmazon = async ( return await enhancedFetch(url); }; -/** - * Add IAP purchase event - * @returns {callback(e: InAppPurchase | ProductPurchase)} - */ -export const purchaseUpdatedListener = ( - listener: (event: InAppPurchase | SubscriptionPurchase) => void, -): EmitterSubscription => { - const emitterSubscription = new NativeEventEmitter( - getNativeModule(), - ).addListener('purchase-updated', listener); - - if (isAndroid) { - getAndroidModule().startListening(); - } - - return emitterSubscription; -}; - -/** - * Add IAP purchase error event - * @returns {callback(e: PurchaseError)} - */ -export const purchaseErrorListener = ( - listener: (errorEvent: PurchaseError) => void, -): EmitterSubscription => - new NativeEventEmitter(getNativeModule()).addListener( - 'purchase-error', - listener, - ); - -/** - * Add IAP promoted subscription event - * Only available on iOS - */ -export const promotedProductListener = ( - listener: (productId?: string) => void, -): EmitterSubscription | null => { - if (isIos) { - return new NativeEventEmitter(getIosModule()).addListener( - 'iap-promoted-product', - listener, - ); - } - return null; -}; - /** * Get the current receipt base64 encoded in IOS. * @param {forceRefresh?:boolean} diff --git a/src/index.ts b/src/index.ts index ee2bbf131..f031ed6b1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,6 @@ export * from './iap'; export * from './types'; +export * from './eventEmitter'; export * from './hooks/useIAP'; export * from './hooks/withIAPContext'; export * from './purchaseError';