import { NativeModules, NativeEventEmitter, DeviceEventEmitter, Platform } from 'react-native' const { RNBranch, RNBranchEventEmitter } = NativeModules import createBranchUniversalObject from './branchUniversalObject' import BranchEvent from './BranchEvent' const packageFile = require('./../package.json') export const VERSION = packageFile.version export const AddToCartEvent = RNBranch.ADD_TO_CART_EVENT export const AddToWishlistEvent = RNBranch.ADD_TO_WISHLIST_EVENT export const PurchasedEvent = RNBranch.PURCHASED_EVENT export const PurchaseInitiatedEvent = RNBranch.PURCHASE_INITIATED_EVENT export const RegisterViewEvent = RNBranch.REGISTER_VIEW_EVENT export const ShareCompletedEvent = RNBranch.SHARE_COMPLETED_EVENT export const ShareInitiatedEvent = RNBranch.SHARE_INITIATED_EVENT class Branch { nativeEventEmitter = Platform.select({ android: DeviceEventEmitter, ios: new NativeEventEmitter(RNBranchEventEmitter) }) key = null; _checkCachedEvents = true; _debug = false; constructor(options = {}) { if (options.debug) this._debug = true console.info('Initializing react-native-branch v. ' + VERSION) } subscribe(listener) { /* * If _checkCachedEvents flag is set, get the cached value from the native layer (asynchronously). * If none, the listener is not called. If there is a cached value, it is passed to the listener. */ if (this._checkCachedEvents) { this._checkCachedEvents = false RNBranch.redeemInitSessionResult().then((result) => { if (result) { /*** Cached value is returned, so set it as cached. ***/ if('params' in result && !!result['params']) { result['params']['+rn_cached_initial_event'] = true } listener(result) } /* * https://github.com/BranchMetrics/react-native-branch-deep-linking/issues/79 * * By waiting until redeemInitSessionResult() returns, we roughly simulate a * synchronous call to the native layer. * * Note that this is equivalent to * * let result = await RNBranch.redeemInitSessionResult() * if (result) listener(result) * this._addListener(listener) * * But by using then(), the subscribe method does not have to be async. * This way, we don't add event listeners until the listener has received the * initial cached value, which essentially eliminates all possibility of * getting the same event twice. */ this._addListener(listener) }) } else { this._addListener(listener) } // Initialize the native Branch SDK from JS // -- Unsupportable on Android for the time being. // RNBranch.initializeBranch(this.key) const unsubscribe = () => { this._removeListener(listener) } return unsubscribe } skipCachedEvents() { /*** Sets to ignore cached events. ***/ this._checkCachedEvents = false } _addListener(listener) { this.nativeEventEmitter.addListener(RNBranch.INIT_SESSION_SUCCESS, listener) this.nativeEventEmitter.addListener(RNBranch.INIT_SESSION_ERROR, listener) } _removeListener(listener) { this.nativeEventEmitter.removeListener(RNBranch.INIT_SESSION_SUCCESS, listener) this.nativeEventEmitter.removeListener(RNBranch.INIT_SESSION_ERROR, listener) } /*** Tracking related methods ***/ disableTracking = (disable) => RNBranch.disableTracking(disable) isTrackingDisabled = RNBranch.isTrackingDisabled /*** RNBranch singleton methods ***/ setDebug = () => { throw 'setDebug() is not supported in the RN SDK. For other solutions, please see https://rnbranch.app.link/setDebug' } getLatestReferringParams = RNBranch.getLatestReferringParams getFirstReferringParams = RNBranch.getFirstReferringParams setIdentity = (identity) => RNBranch.setIdentity(identity) logout = RNBranch.logout userCompletedAction = (event, state = {}) => RNBranch.userCompletedAction(event, state) getShortUrl = RNBranch.getShortUrl sendCommerceEvent = (revenue, metadata) => { console.info('[Branch] sendCommerceEvent is deprecated. Please use the BranchEvent class instead.') return RNBranch.sendCommerceEvent('' + revenue, metadata) } openURL = (url, options = {}) => { return Platform.select({ android: () => RNBranch.openURL(url, options), ios: () => RNBranch.openURL(url) })() } /*** Referral Methods ***/ redeemRewards = (amount, bucket) => RNBranch.redeemRewards(amount, bucket) loadRewards = (bucket) => RNBranch.loadRewards(bucket) getCreditHistory = RNBranch.getCreditHistory /*** BranchUniversalObject ***/ createBranchUniversalObject = createBranchUniversalObject } export { Branch, BranchEvent } export default new Branch()