import { EventEmitter as NativeEventEmitter, NativeModulesProxy } from '@unimodules/core'; import { EventEmitter, EventSubscription } from 'fbemitter'; const { CTKNativeAdManager } = NativeModulesProxy; const nativeAdEmitter = new NativeEventEmitter(CTKNativeAdManager); const EVENT_DID_BECOME_VALID = 'AdsManagerDidBecomeValid'; const EVENT_DID_ERROR = 'AdsManagerDidError'; type AdManagerCachePolicy = 'none' | 'icon' | 'image' | 'all'; interface CTKNativeAdManagerErrorEvent { placementId: string; error: { code: number; message: string; }; } class NativeAdsManager { /** {@string} with placement id of ads **/ placementId: string; /** {@number} of ads to request at once **/ adsToRequest: number; /** {@boolean} indicating whether AdsManager is ready to serve ads **/ isValid: boolean = false; /** {@EventEmitter} used for sending out updates **/ eventEmitter: EventEmitter = new EventEmitter(); static async registerViewsForInteractionAsync( nativeAdViewTag: number, mediaViewTag: number, adIconViewTag: number, clickable: number[] ) { return await CTKNativeAdManager.registerViewsForInteraction( nativeAdViewTag, mediaViewTag, adIconViewTag, clickable ); } static triggerEvent(nativeAdViewTag: number) { return CTKNativeAdManager.triggerEvent(nativeAdViewTag); } /** * Creates an instance of AdsManager with a given placementId and adsToRequest. * Default number of ads to request is `10`. * * AdsManager will become loading ads immediately */ constructor(placementId: string, adsToRequest: number = 10) { this.placementId = placementId; this.adsToRequest = adsToRequest; this._listenForStateChanges(); CTKNativeAdManager.init(placementId, adsToRequest); } /** * Listens for AdManager state changes and updates internal state. When it changes, * callers will be notified of a change */ _listenForStateChanges() { nativeAdEmitter.addListener('CTKNativeAdsManagersChanged', (managers: any) => { const isValidNew = managers[this.placementId]; const isValid = this.isValid; if (isValid !== isValidNew && isValidNew) { this.isValid = true; this.eventEmitter.emit(EVENT_DID_BECOME_VALID); } }); nativeAdEmitter.addListener( 'CTKNativeAdManagerErrored', ({ placementId, error: { code, message } }: CTKNativeAdManagerErrorEvent) => { if (this.placementId === placementId) { const error = new Error(`Facebook Ads could not load (code ${code}): ${message}`); this.eventEmitter.emit(EVENT_DID_ERROR, error); } } ); } /** * Used to listening for state changes * * If manager already became valid, it will call the function w/o registering * handler for events */ onAdsLoaded(listener: () => void): EventSubscription { if (this.isValid) { setImmediate(listener); return { remove: () => {}, } as EventSubscription; } return this.eventEmitter.once(EVENT_DID_BECOME_VALID, listener); } onAdsErrored(listener: (error: Error) => void): EventSubscription { return this.eventEmitter.addListener(EVENT_DID_ERROR, listener); } /** * Disables auto refreshing for this native ad manager */ disableAutoRefresh() { CTKNativeAdManager.disableAutoRefresh(this.placementId); } /** * Set the native ads manager caching policy. This controls which media from * the native ads are cached before the onAdsLoaded is called. * The default is to not block on caching. */ setMediaCachePolicy(cachePolicy: AdManagerCachePolicy) { CTKNativeAdManager.setMediaCachePolicy(this.placementId, cachePolicy); } } export default NativeAdsManager;