Skip to content

Commit 9fa9c55

Browse files
committedAug 29, 2024
release v0.7.3
1 parent 23e9f4c commit 9fa9c55

18 files changed

+255
-194
lines changed
 

‎android/src/main/java/com/ammarahmed/rnadmob/nativeads/EventEmitter.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@
22

33
import androidx.annotation.Nullable;
44

5+
import com.facebook.react.bridge.Arguments;
56
import com.facebook.react.bridge.ReactContext;
67
import com.facebook.react.bridge.WritableMap;
78
import com.facebook.react.modules.core.DeviceEventManagerModule;
89

910
public class EventEmitter {
1011

1112
public static void sendEvent(ReactContext reactContext, String eventName, @Nullable WritableMap params) {
12-
reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(eventName, params);
13+
reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(eventName, params != null ? params : Arguments.createMap());
1314
}
1415

1516
}

‎android/src/main/java/com/ammarahmed/rnadmob/nativeads/RNAdMobUnifiedAdQueueWrapper.java

+17-8
Original file line numberDiff line numberDiff line change
@@ -81,19 +81,20 @@ public void onAdFailedToLoad(LoadAdError adError) {
8181
error.putInt("code", adError.getCode());
8282
error.putString("domain", adError.getDomain());
8383
event.putMap("error", error);
84-
EventEmitter.sendEvent((ReactContext) mContext, CacheManager.EVENT_AD_PRELOAD_ERROR + ":" + name, event);
84+
85+
EventEmitter.sendEvent(mContext, CacheManager.EVENT_AD_PRELOAD_ERROR + ":" + name, event);
8586
notifyOnAdsLoadFailed(adError);
8687
return;
8788
}
8889

8990
if (retryCount >= totalRetryCount) {
90-
WritableMap event = Arguments.createMap();
91+
WritableMap event = getDefaultEventData();
9192
WritableMap error = Arguments.createMap();
9293
error.putString("message", "reach maximum retry");
9394
error.putInt("code", AdRequest.ERROR_CODE_INTERNAL_ERROR);
9495
error.putString("domain", "");
9596
event.putMap("error", error);
96-
EventEmitter.sendEvent((ReactContext) mContext, CacheManager.EVENT_AD_PRELOAD_ERROR + ":" + name, event);
97+
EventEmitter.sendEvent( mContext, CacheManager.EVENT_AD_PRELOAD_ERROR + ":" + name, event);
9798
notifyOnAdsLoadFailed(adError);
9899
return;
99100
}
@@ -110,36 +111,38 @@ public void run() {
110111
@Override
111112
public void onAdImpression() {
112113
super.onAdImpression();
113-
EventEmitter.sendEvent((ReactContext) mContext, CacheManager.EVENT_AD_IMPRESSION + ":" + name, null);
114+
EventEmitter.sendEvent(mContext, CacheManager.EVENT_AD_IMPRESSION + ":" + name, getDefaultEventData());
114115

115116
}
116117

117118
@Override
118119
public void onAdClosed() {
119120
super.onAdClosed();
120-
EventEmitter.sendEvent((ReactContext) mContext, CacheManager.EVENT_AD_CLOSED + ":" + name, null);
121+
WritableMap map = Arguments.createMap();
122+
EventEmitter.sendEvent(mContext, CacheManager.EVENT_AD_CLOSED + ":" + name, getDefaultEventData());
121123

122124
}
123125

124126
@Override
125127
public void onAdOpened() {
126128
super.onAdOpened();
127-
EventEmitter.sendEvent((ReactContext) mContext, CacheManager.EVENT_AD_OPEN + ":" + name, null);
129+
EventEmitter.sendEvent(mContext, CacheManager.EVENT_AD_OPEN + ":" + name, getDefaultEventData());
128130

129131
}
130132

131133
@Override
132134
public void onAdClicked() {
133135
super.onAdClicked();
134-
Log.d("RNADMOB", CacheManager.EVENT_AD_CLICKED + ":" + name);
135-
EventEmitter.sendEvent((ReactContext) mContext, CacheManager.EVENT_AD_CLICKED + ":" + name, null);
136+
EventEmitter.sendEvent(mContext, CacheManager.EVENT_AD_CLICKED + ":" + name, getDefaultEventData());
136137

137138
}
138139

139140
@Override
140141
public void onAdLoaded() {
141142
super.onAdLoaded();
142143

144+
EventEmitter.sendEvent(mContext, CacheManager.EVENT_AD_PRELOAD_LOADED + ":" + name, getDefaultEventData());
145+
143146
retryCount = 0;
144147
if (mediation) {
145148
loadingAdRequestCount--;
@@ -154,7 +157,13 @@ public void onAdLoaded() {
154157
};
155158

156159
setConfiguration(config);
160+
}
157161

162+
private WritableMap getDefaultEventData() {
163+
WritableMap map = Arguments.createMap();
164+
map.putString("adUnitId", adUnitId);
165+
map.putString("repo", name);
166+
return map;
158167
}
159168

160169
private void notifyOnAdsLoadFailed(LoadAdError adError){

‎android/src/main/java/com/ammarahmed/rnadmob/nativeads/RNAdmobNativeView.java

+9-14
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
package com.ammarahmed.rnadmob.nativeads;
22

33
import android.content.Context;
4-
import android.graphics.Color;
54
import android.os.Handler;
65
import android.view.LayoutInflater;
76
import android.view.View;
8-
import android.view.ViewGroup;
97
import android.widget.LinearLayout;
108

119
import androidx.annotation.NonNull;
@@ -18,15 +16,13 @@
1816
import com.facebook.react.bridge.WritableArray;
1917
import com.facebook.react.bridge.WritableMap;
2018
import com.facebook.react.bridge.WritableNativeArray;
21-
import com.facebook.react.bridge.WritableNativeMap;
2219
import com.facebook.react.uimanager.events.RCTEventEmitter;
2320
import com.google.android.gms.ads.AdListener;
2421
import com.google.android.gms.ads.AdLoader;
2522
import com.google.android.gms.ads.LoadAdError;
2623
import com.google.android.gms.ads.MediaContent;
2724
import com.google.android.gms.ads.VideoOptions;
2825
import com.google.android.gms.ads.admanager.AdManagerAdRequest;
29-
import com.google.android.gms.ads.nativead.AdChoicesView;
3026
import com.google.android.gms.ads.nativead.MediaView;
3127
import com.google.android.gms.ads.nativead.NativeAd;
3228
import com.google.android.gms.ads.nativead.NativeAdOptions;
@@ -67,7 +63,6 @@ public class RNAdmobNativeView extends LinearLayout {
6763
private Handler handler;
6864

6965
AdListener adListener = new AdListener() {
70-
7166
@Override
7267
public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) {
7368
super.onAdFailedToLoad(loadAdError);
@@ -126,11 +121,6 @@ public void onNativeAdLoaded(NativeAd ad) {
126121
if (nativeAd != null) {
127122
nativeAd.destroy();
128123
}
129-
130-
if (ad != null) {
131-
nativeAd = ad;
132-
setNativeAd();
133-
}
134124
loadingAd = false;
135125
setNativeAdToJS(ad);
136126
}
@@ -185,9 +175,10 @@ private Method getDeclaredMethod(Object obj, String name) {
185175
return null;
186176
}
187177

188-
private void setNativeAdToJS(NativeAd nativeAd) {
189-
178+
private void setNativeAdToJS(NativeAd ad) {
190179
try {
180+
nativeAd = ad;
181+
setNativeAd();
191182
WritableMap args = Arguments.createMap();
192183
args.putString("headline", nativeAd.getHeadline());
193184
args.putString("tagline", nativeAd.getBody());
@@ -307,12 +298,13 @@ private void getAdFromRepository() {
307298
unifiedNativeAdContainer = CacheManager.instance.getNativeAd(adRepo);
308299

309300
if (unifiedNativeAdContainer != null) {
301+
if (nativeAd != null) {
302+
nativeAd.destroy();
303+
}
310304
nativeAd = unifiedNativeAdContainer.unifiedNativeAd;
311-
nativeAdView.setNativeAd(nativeAd);
312305
if (mediaView != null) {
313306
nativeAdView.setMediaView(mediaView);
314307
mediaView.requestLayout();
315-
setNativeAd();
316308
}
317309
setNativeAdToJS(nativeAd);
318310
}
@@ -394,6 +386,9 @@ public void setNativeAd() {
394386
mediaView.setMedia(nativeAd.getMediaContent());
395387
}
396388
}
389+
handler.postDelayed(() -> {
390+
nativeAdView.getRootView().requestLayout();
391+
}, 1000);
397392

398393
}
399394
}

‎example/App.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@ import List from "./src/List";
1616
import { routes } from "./src/utils";
1717
import Icon from "react-native-vector-icons/MaterialCommunityIcons";
1818
const App = () => {
19-
const [currentRoute, setCurrentRoute] = useState(null);
19+
const [currentRoute, setCurrentRoute] = useState({
20+
type: "banner",
21+
index: 0
22+
});
2023
const [loading, setLoading] = useState(true);
2124

2225
useEffect(() => {

‎example/index.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,12 @@ AdManager.registerRepository({
5050
console.log('registered: ', result);
5151
});
5252

53-
AdManager.subscribe('imageAd', 'onAdPreloadClicked', () => {
54-
console.log('click', 'imageAd');
53+
AdManager.subscribe('imageAd', 'onAdPreloadClicked', (event) => {
54+
console.log('click', 'imageAd', event);
5555
});
5656

57-
AdManager.subscribe("imageAd", "onAdPreloadImpression", () => {
58-
console.log('impression recorded', 'imageAd');
57+
AdManager.subscribe("imageAd", "onAdPreloadImpression", (event) => {
58+
console.log('impression recorded', 'imageAd', event);
5959
});
6060

6161
AppRegistry.registerComponent(appName, () => App);

‎example/src/AdView.js

+7-9
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
import React, {useCallback, useEffect, useRef, useState} from 'react';
1+
import React, { useEffect, useRef, useState } from 'react';
22
import {
33
ActivityIndicator,
4-
DeviceEventEmitter,
54
Platform,
65
Text,
7-
View,
6+
View
87
} from 'react-native';
98
import NativeAdView, {
109
AdvertiserView,
@@ -13,11 +12,10 @@ import NativeAdView, {
1312
IconView,
1413
StarRatingView,
1514
StoreView,
16-
TaglineView,
17-
TestIds,
15+
TaglineView
1816
} from 'react-native-admob-native-ads';
19-
import {MediaView} from './MediaView';
20-
import {Events, Logger} from './utils';
17+
import { MediaView } from './MediaView';
18+
import { Logger } from './utils';
2119

2220
export const AdView = React.memo(({index, media, type, loadOnMount = true}) => {
2321
const [aspectRatio, setAspectRatio] = useState(1.5);
@@ -101,8 +99,8 @@ export const AdView = React.memo(({index, media, type, loadOnMount = true}) => {
10199
mediationOptions={{
102100
nativeBanner: true,
103101
}}
104-
adUnitID={type === 'image' ? TestIds.Image : TestIds.Video} // REPLACE WITH NATIVE_AD_VIDEO_ID for video ads.
105-
// repository={type === 'image' ? 'imageAd' : 'videoAd'}
102+
// adUnitID={type === 'image' ? TestIds.Image : TestIds.Video} // REPLACE WITH NATIVE_AD_VIDEO_ID for video ads.
103+
repository={type === 'image' ? 'imageAd' : 'videoAd'}
106104
>
107105
<View
108106
style={{

‎index.d.ts

+14-7
Original file line numberDiff line numberDiff line change
@@ -166,8 +166,8 @@ type AdRepositoryConfig = {
166166
targetingOptions?: TargetingOptions;
167167
adChoicesPlacement?: "topLeft" | "topRight" | "bottomLeft" | "bottomRight";
168168
mediaAspectRatio?: "any" | "landscape" | "portrait" | "square" | "unknown";
169-
swipeGestureDirection?: "right" | "left" | "up" | "down",
170-
tapsAllowed?: boolean
169+
swipeGestureDirection?: "right" | "left" | "up" | "down";
170+
tapsAllowed?: boolean;
171171
};
172172

173173
type ImagePropsWithOptionalSource = Omit<ImageProps, "source"> &
@@ -255,8 +255,8 @@ type NativeAdViewProps = {
255255
targetingOptions?: TargetingOptions;
256256
enableSwipeGestureOptions: {
257257
tapsAllowed?: boolean;
258-
swipeGestureDirection?: "right" | "left" | "up" | "down";
259-
}
258+
swipeGestureDirection?: "right" | "left" | "up" | "down";
259+
};
260260

261261
testDevices?: Array<string>;
262262
onAdOpened?: () => void;
@@ -267,7 +267,6 @@ type NativeAdViewProps = {
267267
onAdLoaded?: () => void;
268268
onNativeAdLoaded?: (event: NativeAd) => void;
269269
onAdFailedToLoad?: (error: { message: string }) => void;
270-
adBadgeProps: NestedTextProps
271270
};
272271

273272
type SimpleViewProps = {
@@ -415,11 +414,19 @@ declare module "react-native-admob-native-ads" {
415414
| "onAdPreloadClosed"
416415
| "onAdPreloadClicked"
417416
| "onAdPreloadImpression",
418-
listener
417+
listener: (event: {
418+
adUnitId: string;
419+
repo: string;
420+
error?: {
421+
message: string;
422+
code: number;
423+
domain: string;
424+
};
425+
}) => void
419426
) => EmitterSubscription;
420427

421428
openAdInspector: () => void;
422-
openDebugMenu: (adUnitId: string) => void
429+
openDebugMenu: (adUnitId: string) => void;
423430
};
424431

425432
export const AdOptions: options;

‎ios/RNAdMobManager/EventEmitter.m

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ - (void)sendEvent:(NSString *) name dict:(NSDictionary *)dict
5353
{
5454

5555
if (hasListeners) { // Only send events if anyone is listening
56-
[self sendEventWithName:name body:dict];
56+
[self sendEventWithName:name body:dict ? dict : [NSDictionary dictionary]];
5757
}
5858
}
5959
@end

‎ios/RNAdMobManager/RNAdMobUnifiedAdQueueWrapper.m

+120-79
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,13 @@
1919
@implementation RNAdMobUnifiedAdQueueWrapper{
2020
GADAdLoader* adLoader;
2121
GAMRequest* adRequest;
22-
22+
2323
NSMutableSet<id<AdListener>>* attachedAdListeners;
2424
UnifiedNativeAdLoadedListener* unifiedNativeAdLoadedListener;
2525
GADVideoOptions* adVideoOptions;
2626
GADNativeAdMediaAdLoaderOptions* adMediaOptions;
2727
GADNativeAdViewAdOptions* adPlacementOptions;
28+
GADNativeAdCustomClickGestureOptions *clickGestureOptions;
2829
NSDictionary* targetingOptions;
2930
int loadingAdRequestCount;
3031
int retryDelay;
@@ -45,10 +46,10 @@ -(instancetype)initWithConfig:(NSDictionary *)config repo:(NSString *)repo{
4546
adVideoOptions = [[GADVideoOptions alloc]init];
4647
adMediaOptions = [[GADNativeAdMediaAdLoaderOptions alloc] init];
4748
adPlacementOptions = [[GADNativeAdViewAdOptions alloc]init];
48-
49+
4950
attachedAdListeners = [[NSMutableSet<id<AdListener>> alloc] init];
5051
}
51-
52+
5253
//Set repository settings
5354
_adUnitId = [config objectForKey:@"adUnitId"] ;
5455
_name = repo;
@@ -58,29 +59,29 @@ -(instancetype)initWithConfig:(NSDictionary *)config repo:(NSString *)repo{
5859
if ([config objectForKey:@"totalRetryCount"]){
5960
totalRetryCount = ((NSNumber *)[config objectForKey:@"totalRetryCount"]).boolValue;
6061
}
61-
62+
6263
if ([config objectForKey:@"retryDelay"]){
6364
retryDelay = ((NSNumber *)[config objectForKey:@"retryDelay"]).boolValue;
6465
}
65-
66+
6667
_nativeAds = [[NSMutableArray<RNAdMobUnifiedAdContainer *> alloc]init];
67-
68+
6869
if ([config objectForKey:@"expirationPeriod"]){
6970
_expirationInterval = ((NSNumber *)[config objectForKey:@"expirationPeriod"]).intValue;
7071
}
7172
if ([config objectForKey:@"mediationEnabled"]){
7273
_isMediationEnabled = ((NSNumber *)[config objectForKey:@"mediationEnabled"]).boolValue;
7374
}
74-
75-
75+
76+
7677
//Set request options
7778
if ([config objectForKey:@"adChoicesPlacement"]){
7879
[adPlacementOptions setPreferredAdChoicesPosition:((NSNumber *)[config objectForKey:@"adChoicesPlacement"]).intValue];
7980
}
8081
if ([config objectForKey:@"mediaAspectRatio"]){
8182
[adMediaOptions setMediaAspectRatio:((NSNumber *)[config objectForKey:@"mediaAspectRatio"]).intValue];
8283
}
83-
84+
8485
if ([config objectForKey:@"videoOptions"]){
8586
[self configVideoOptions:[config objectForKey:@"videoOptions"]];
8687
}
@@ -90,15 +91,38 @@ -(instancetype)initWithConfig:(NSDictionary *)config repo:(NSString *)repo{
9091
if ([config objectForKey:@"targetingOptions"]){
9192
[self configTargetOptions:[config objectForKey:@"targetingOptions"]];
9293
}
93-
94-
94+
95+
if ([config valueForKey:@"swipeGestureDirection"]) {
96+
97+
clickGestureOptions = [[GADNativeAdCustomClickGestureOptions alloc] initWithSwipeGestureDirection:UISwipeGestureRecognizerDirectionUp tapsAllowed:false];
98+
99+
int direction = ((NSNumber *)[config objectForKey:@"swipeGestureDirection"]).intValue;
100+
101+
if (direction == 1) {
102+
[clickGestureOptions setSwipeGestureDirection:UISwipeGestureRecognizerDirectionRight];
103+
} else if (direction == 2) {
104+
[clickGestureOptions setSwipeGestureDirection:UISwipeGestureRecognizerDirectionLeft];
105+
} else if (direction == 4) {
106+
[clickGestureOptions setSwipeGestureDirection:UISwipeGestureRecognizerDirectionUp];
107+
} else if (direction == 8) {
108+
[clickGestureOptions setSwipeGestureDirection:UISwipeGestureRecognizerDirectionDown];
109+
}
110+
111+
if ([config valueForKey:@"tapsAllowed"]) {
112+
[clickGestureOptions setTapsAllowed:[config valueForKey:@"tapsAllowed"]];
113+
}
114+
}
115+
116+
117+
118+
95119
if ([config objectForKey:@"requestNonPersonalizedAdsOnly"]){
96120
GADCustomEventExtras *extras = [[GADCustomEventExtras alloc] init];
97121
bool npa = ((NSNumber *)[config objectForKey:@"requestNonPersonalizedAdsOnly"]).boolValue;
98122
[extras setExtras:@{@"npa": @([NSNumber numberWithInt:npa].intValue)} forLabel:@"npa"];
99123
[adRequest registerAdNetworkExtras:extras];
100124
}
101-
125+
102126
unifiedNativeAdLoadedListener = [[UnifiedNativeAdLoadedListener alloc]initWithRepo:repo nativeAds:_nativeAds tAds:_totalAds];
103127
return self;
104128
}
@@ -114,22 +138,27 @@ -(void) detachAdListener:(id<AdListener>) listener{
114138
if use mediation,you can't use GADMultipleAdsAdLoaderOptions for load ads
115139
*/
116140
-(void) fillAds{
117-
141+
118142
int require2fill = _totalAds-((int)_nativeAds.count);
119-
143+
120144
if ( [self isLoading] || require2fill<=0){
121145
return;
122146
}
147+
123148
NSMutableArray<GADAdLoaderOptions *>* options = [NSMutableArray arrayWithArray:@[adMediaOptions,adVideoOptions,adPlacementOptions]];
124-
149+
150+
if (clickGestureOptions) {
151+
[options addObject:clickGestureOptions];
152+
}
153+
125154
if (!_isMediationEnabled) {
126155
GADMultipleAdsAdLoaderOptions* multipleAdsOptions = [[GADMultipleAdsAdLoaderOptions alloc] init];
127156
multipleAdsOptions.numberOfAds = MAX(require2fill,0);
128157
[options addObject:multipleAdsOptions];
129158
}
130159
adLoader = [[GADAdLoader alloc] initWithAdUnitID:_adUnitId rootViewController:nil adTypes:@[GADAdLoaderAdTypeNative] options:options];
131160
[adLoader setDelegate:self];
132-
161+
133162
loadingAdRequestCount = require2fill;
134163
if(_isMediationEnabled){
135164
printf("admob request count:",MIN(require2fill,5));
@@ -144,14 +173,14 @@ -(void) fillAds{
144173
-(RNAdMobUnifiedAdContainer*) getAd{
145174
long long now = (long long)([[NSDate date] timeIntervalSince1970] * 1000.0);
146175
RNAdMobUnifiedAdContainer *ad = nil;
147-
176+
148177
if (!(_nativeAds.count == 0)){
149178
//sortAds
150179
[_nativeAds sortUsingComparator:^NSComparisonResult(id<Comparable, NSObject> _Nonnull obj1,
151180
id<Comparable, NSObject> _Nonnull obj2) {
152181
return [obj1 compareTo:obj2] > 0; //find lowest showCount
153182
}];
154-
183+
155184
NSMutableArray<RNAdMobUnifiedAdContainer *> *discardedItems = [NSMutableArray<RNAdMobUnifiedAdContainer *> array];
156185
for (RNAdMobUnifiedAdContainer *item in self.nativeAds) {
157186
if (item != nil && (now - item.loadTime) < _expirationInterval) {
@@ -188,89 +217,101 @@ - (void)adLoader:(nonnull GADAdLoader *)adLoader didReceiveNativeAd:(nonnull GAD
188217
loadingAdRequestCount--;
189218
retryCount = 0;
190219
[unifiedNativeAdLoadedListener adLoader:adLoader didReceiveNativeAd:nativeAd];
191-
220+
192221
//to prevent a crash (check the link below), first copy attachedAdListeners into a new array
193222
//link:https://stackoverflow.com/questions/44648610/collection-nsarraym-was-mutated-while-being-enumerated
194223
for (id<AdListener> listener in [attachedAdListeners copy]){
195224
[listener didAdLoaded:nativeAd];
196225
}
197-
[EventEmitter.sharedInstance sendEvent:[CacheManager EVENT_AD_PRELOAD_LOADED:_name] dict:nil];
198-
226+
[EventEmitter.sharedInstance sendEvent:[CacheManager EVENT_AD_PRELOAD_LOADED:_name] dict:[self getDefaultEventData]];
227+
199228
if (loadingAdRequestCount == 0){
200229
[self fillAds];//fill up repository if need
201230
}
202231
// The adLoader has finished loading ads, and a new request can be sent.
203232
}
204233

234+
- (NSMutableDictionary *)getDefaultEventData {
235+
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
236+
[dict setValue:@"adUnitId" forKey:_adUnitId];
237+
[dict setValue:@"repo" forKey:_name];
238+
return dict;
239+
}
240+
205241
- (void)nativeAdDidRecordClick:(GADNativeAd *)nativeAd {
206-
[EventEmitter.sharedInstance sendEvent:[CacheManager EVENT_AD_CLICKED:_name] dict:nil];
242+
[EventEmitter.sharedInstance sendEvent:[CacheManager EVENT_AD_CLICKED:_name] dict:[self getDefaultEventData]];
207243
}
208244

209245
- (void)nativeAdDidRecordImpression:(GADNativeAd *)nativeAd {
210-
[EventEmitter.sharedInstance sendEvent:[CacheManager EVENT_AD_IMPRESSION:_name] dict:nil];
246+
[EventEmitter.sharedInstance sendEvent:[CacheManager EVENT_AD_IMPRESSION:_name] dict:[self getDefaultEventData]];
211247
}
212248

213249
- (void)nativeAdWillPresentScreen:(GADNativeAd *)nativeAd {
214-
[EventEmitter.sharedInstance sendEvent:[CacheManager EVENT_AD_OPEN:_name] dict:nil];
250+
[EventEmitter.sharedInstance sendEvent:[CacheManager EVENT_AD_OPEN:_name] dict:[self getDefaultEventData]];
215251
}
216252

217253
- (void)nativeAdDidDismissScreen:(GADNativeAd *)nativeAd {
218-
[EventEmitter.sharedInstance sendEvent:[CacheManager EVENT_AD_CLOSED:_name] dict:nil];
254+
[EventEmitter.sharedInstance sendEvent:[CacheManager EVENT_AD_CLOSED:_name] dict:[self getDefaultEventData]];
219255
}
220256

221257
- (void)adLoader:(nonnull GADAdLoader *)adLoader didFailToReceiveAdWithError:(nonnull NSError *)error {
222-
if(_isMediationEnabled){
223-
loadingAdRequestCount--;
224-
}else{
225-
loadingAdRequestCount = 0;
226-
}
227-
258+
if(_isMediationEnabled){
259+
loadingAdRequestCount--;
260+
}else{
261+
loadingAdRequestCount = 0;
262+
}
263+
228264
[unifiedNativeAdLoadedListener adLoader:adLoader didFailToReceiveAdWithError:error];
229-
230-
265+
266+
231267
BOOL stopPreloading = false;
232268
switch (error.code) {
233269
case GADErrorInternalError:
234270
case GADErrorInvalidRequest:
235271
stopPreloading = true;
236272
break;
237273
}
238-
274+
239275
if (stopPreloading) {
276+
240277
NSDictionary *errorDic = @{
241-
@"domain":error.domain,
242-
@"message":error.localizedDescription,
243-
@"code":@(error.code).stringValue
244-
};
245-
NSDictionary *event = @{
246-
@"error":errorDic,
247-
};
248-
249-
[EventEmitter.sharedInstance sendEvent:[CacheManager EVENT_AD_PRELOAD_ERROR:_name] dict:event];
278+
@"domain":error.domain,
279+
@"message":error.localizedDescription,
280+
@"code":@(error.code).stringValue
281+
};
282+
283+
NSMutableDictionary *dict = [self getDefaultEventData];
284+
[dict addEntriesFromDictionary:@{
285+
@"error":errorDic,
286+
}];
287+
288+
[EventEmitter.sharedInstance sendEvent:[CacheManager EVENT_AD_PRELOAD_ERROR:_name] dict:dict];
250289

251-
for (id<AdListener> listener in [attachedAdListeners copy]){
252-
[listener didFailToReceiveAdWithError:error];
253-
}
254-
return;
290+
for (id<AdListener> listener in [attachedAdListeners copy]){
291+
[listener didFailToReceiveAdWithError:error];
292+
}
293+
return;
255294
}
256-
295+
257296
if (retryCount >= totalRetryCount){
258297
NSDictionary *errorDic = @{
259-
@"domain":@"",
260-
@"message":@"reach max retry",
261-
@"code":@""
262-
};
263-
NSDictionary *event = @{
264-
@"error":errorDic,
265-
};
266-
[EventEmitter.sharedInstance sendEvent:[CacheManager EVENT_AD_PRELOAD_ERROR:_name] dict:event];
298+
@"domain":@"",
299+
@"message":@"reach max retry",
300+
@"code":@""
301+
};
302+
NSMutableDictionary *dict = [self getDefaultEventData];
303+
[dict addEntriesFromDictionary:@{
304+
@"error":errorDic,
305+
}];
306+
307+
[EventEmitter.sharedInstance sendEvent:[CacheManager EVENT_AD_PRELOAD_ERROR:_name] dict:dict];
267308
for (id<AdListener> listener in [attachedAdListeners copy]){
268-
[listener didFailToReceiveAdWithError:error];
269-
}
309+
[listener didFailToReceiveAdWithError:error];
310+
}
270311
return;
271312
}
272-
273-
313+
314+
274315
if (loadingAdRequestCount == 0) {
275316
retryCount++;
276317
__weak typeof(self) weakSelf = self;
@@ -279,42 +320,42 @@ - (void)adLoader:(nonnull GADAdLoader *)adLoader didFailToReceiveAdWithError:(no
279320
[weakSelf fillAds];
280321
});
281322
}
282-
323+
283324
}
284325

285326
-(void)configVideoOptions:(NSDictionary *)config{
286-
327+
287328
if ([config objectForKey:@"mute"]) {
288329
bool muted = ((NSNumber *)[config objectForKey:@"mute"]).boolValue;
289330
[adVideoOptions setStartMuted:muted];
290331
}
291-
332+
292333
if ([config objectForKey:@"clickToExpand"]) {
293334
bool clickToExpand = ((NSNumber *)[config objectForKey:@"clickToExpand"]).boolValue;
294335
[adVideoOptions setClickToExpandRequested:clickToExpand];
295336
}
296-
337+
297338
if ([config objectForKey:@"customControlsRequested"]) {
298339
bool customControlsRequested = ((NSNumber *)[config objectForKey:@"customControlsRequested"]).boolValue;
299340
[adVideoOptions setCustomControlsRequested:customControlsRequested];
300341
}
301342
}
302343

303344
-(void)configTargetOptions:(NSDictionary *)config{
304-
345+
305346
if ([config objectForKey:@"targets"]){
306347
NSArray<NSDictionary *>* targets = (NSArray<NSDictionary *> *)[config objectForKey:@"targets"];
307348
for (NSDictionary* target in targets){
308-
[adRequest setCustomTargeting:target];
349+
[adRequest setCustomTargeting:target];
309350
}
310-
351+
311352
if ([config objectForKey:@"categoryExclusions"]){
312353
[adRequest setCategoryExclusions:(NSArray<NSString *> *)[config objectForKey:@"categoryExclusions"]];
313354
}
314355
if ([config objectForKey:@"publisherId"]){
315356
[adRequest setPublisherProvidedID:(NSString *)[config objectForKey:@"publisherId"]];
316357
}
317-
358+
318359
if ([config objectForKey:@"requestAgent"]){
319360
[adRequest setRequestAgent:(NSString *)[config objectForKey:@"requestAgent"]];
320361
}
@@ -327,23 +368,23 @@ -(void)configTargetOptions:(NSDictionary *)config{
327368
if ([config objectForKey:@"neighboringContentUrls"]){
328369
[adRequest setNeighboringContentURLStrings:(NSArray<NSString *> *)[config objectForKey:@"neighboringContentUrls"]];
329370
}
330-
371+
331372
}
332373
}
333374

334375
-(void)configMediationOptions:(NSDictionary *)config{
335376
#ifdef MEDIATION_FACEBOOK
336-
GADFBNetworkExtras * extras = [[GADFBNetworkExtras alloc] init];
337-
338-
if ([config valueForKey:@"nativeBanner"]) {
339-
extras.nativeAdFormat = GADFBAdFormatNative;
340-
} else {
341-
extras.nativeAdFormat = GADFBAdFormatNativeBanner;
342-
}
343-
344-
[adRequest registerAdNetworkExtras:extras];
377+
GADFBNetworkExtras * extras = [[GADFBNetworkExtras alloc] init];
378+
379+
if ([config valueForKey:@"nativeBanner"]) {
380+
extras.nativeAdFormat = GADFBAdFormatNative;
381+
} else {
382+
extras.nativeAdFormat = GADFBAdFormatNativeBanner;
383+
}
384+
385+
[adRequest registerAdNetworkExtras:extras];
345386
#endif
346-
387+
347388
}
348389

349390
@end

‎ios/RNAdMobManager/RNGADMediaView.m

+2
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ - (void)videoControllerDidEndVideoPlayback:(GADVideoController *)videoController
5959
}
6060
}
6161

62+
63+
6264
- (void)getCurrentProgress
6365
{
6466

‎ios/RNAdMobManager/RNGADNativeView.h

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ GADNativeAdDelegate>
3232
@property (nonatomic, copy) NSDictionary *mediationOptions;
3333
@property (nonatomic, copy) NSDictionary *targetingOptions;
3434
@property (nonatomic, copy) NSDictionary *videoOptions;
35+
@property (nonatomic, copy) NSDictionary *enableSwipeGestureOptions;
3536

3637
- (instancetype)initWithBridge:(RCTBridge *)bridge;
3738

‎ios/RNAdMobManager/RNGADNativeView.m

+32-2
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ @implementation RNGADNativeView : GADNativeAdView
4040

4141
GADNativeAdViewAdOptions *adPlacementOptions;
4242
GADNativeAdMediaAdLoaderOptions *adMediaOptions;
43-
43+
GADNativeAdCustomClickGestureOptions *clickGestureOptions;
4444
GAMRequest *adRequest;
4545
GADVideoOptions *adVideoOptions;
4646

@@ -79,6 +79,29 @@ - (void) willMoveToSuperview: (UIView *) newSuperview{
7979
}
8080
}
8181

82+
- (void) setEnableSwipeGestureOptions:(NSDictionary *)enableSwipeGestureOptions {
83+
84+
clickGestureOptions = [[GADNativeAdCustomClickGestureOptions alloc] initWithSwipeGestureDirection:UISwipeGestureRecognizerDirectionUp tapsAllowed:false];
85+
86+
if ([enableSwipeGestureOptions valueForKey:@"swipeGestureDirection"]) {
87+
int direction = ((NSNumber *)[enableSwipeGestureOptions objectForKey:@"swipeGestureDirection"]).intValue;
88+
89+
if (direction == 1) {
90+
[clickGestureOptions setSwipeGestureDirection:UISwipeGestureRecognizerDirectionRight];
91+
} else if (direction == 2) {
92+
[clickGestureOptions setSwipeGestureDirection:UISwipeGestureRecognizerDirectionLeft];
93+
} else if (direction == 4) {
94+
[clickGestureOptions setSwipeGestureDirection:UISwipeGestureRecognizerDirectionUp];
95+
} else if (direction == 8) {
96+
[clickGestureOptions setSwipeGestureDirection:UISwipeGestureRecognizerDirectionDown];
97+
}
98+
}
99+
100+
if ([enableSwipeGestureOptions valueForKey:@"tapsAllowed"]) {
101+
[clickGestureOptions setTapsAllowed:[enableSwipeGestureOptions valueForKey:@"tapsAllowed"]];
102+
}
103+
}
104+
82105
- (void)setMediationOptions:(NSDictionary *)mediationOptions {
83106
NSArray *allKeys = [mediationOptions allKeys];
84107
if ([allKeys containsObject:@"nativeBanner"]) {
@@ -479,10 +502,17 @@ - (void)loadAd
479502
- (void) requestAd{
480503
if (isLoading == TRUE) return;
481504
isLoading = TRUE;
505+
506+
NSMutableArray<GADAdLoaderOptions *>* options = [NSMutableArray arrayWithArray:@[adMediaOptions,adVideoOptions,adPlacementOptions]];
507+
508+
if (clickGestureOptions) {
509+
[options addObject:clickGestureOptions];
510+
}
511+
482512
self.adLoader = [[GADAdLoader alloc] initWithAdUnitID:adUnitId
483513
rootViewController:self.reactViewController
484514
adTypes:@[ GADAdLoaderAdTypeNative ]
485-
options:@[adMediaOptions,adPlacementOptions,adVideoOptions]];
515+
options:options];
486516

487517

488518
self.adLoader.delegate = self;

‎ios/RNAdMobManager/RNGADNativeViewManager.m

+1
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ -(UIView *)view
5959
RCT_EXPORT_VIEW_PROPERTY(requestNonPersonalizedAdsOnly, BOOL)
6060
RCT_EXPORT_VIEW_PROPERTY(adChoicesPlacement, NSNumber)
6161
RCT_EXPORT_VIEW_PROPERTY(repository, NSString)
62+
RCT_EXPORT_VIEW_PROPERTY(enableSwipeGestureOptions, NSDictionary)
6263

6364
RCT_EXPORT_VIEW_PROPERTY(onSizeChange, RCTDirectEventBlock)
6465
RCT_EXPORT_VIEW_PROPERTY(onAppEvent, RCTDirectEventBlock)

‎package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-native-admob-native-ads",
3-
"version": "0.7.2",
3+
"version": "0.7.3",
44
"description": "A simple and robust library for creating & displaying Admob Native Ads in your React Native App using Native Views",
55
"author": "Ammar Ahmed <ammarahmed6506@gmail.com>",
66
"main": "index.js",

‎src/AdBadge.js

+31-16
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,44 @@
11
import React from "react";
2-
import { StyleSheet, Text } from "react-native";
2+
import { View, Text, StyleSheet } from "react-native";
33

44
const AdBadge = ({allCaps,textStyle,style}) => {
55
return (
6-
<Text
7-
style={[
8-
styles.text,
9-
textStyle,
10-
]}
11-
>
12-
{allCaps ? 'AD' : 'AD'}
13-
</Text>
6+
<View
7+
style={[
8+
styles.container,
9+
style,
10+
]}
11+
>
12+
<Text
13+
style={[
14+
styles.text,
15+
textStyle,
16+
]}
17+
>
18+
{allCaps ? 'AD' : 'AD'}
19+
</Text>
20+
</View>
1421
);
1522
};
1623

1724
export default AdBadge;
1825

1926
const styles = StyleSheet.create({
27+
container: {
28+
height: 17,
29+
width: 21,
30+
borderWidth: 1,
31+
borderRadius: 2.5,
32+
left: 0,
33+
top: 0,
34+
justifyContent:'center',
35+
alignItems:'center',
36+
paddingHorizontal: 1,
37+
position:"absolute",
38+
39+
},
2040
text: {
21-
color: "green",
22-
fontSize: 10,
23-
fontWeight:"bold",
24-
position:"absolute",
25-
left: 1,
26-
top: 1,
27-
zIndex: 999
41+
fontSize: 12,
42+
fontWeight:"bold"
2843
}
2944
})

‎src/AdManager.js

+1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ async function resetCache() {
5353
}
5454

5555
function subscribe(repo, eventName, listener) {
56+
console.log('subscribed: ', `${eventName}:${repo}`);
5657
return DeviceEventEmitter.addListener(`${eventName}:${repo}`, listener);
5758
}
5859

‎src/Wrapper.js

+3-42
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,12 @@
1-
import React, { useContext, useEffect, useRef, useState } from "react";
2-
import { ScrollView, StyleSheet } from "react-native";
3-
import { NativeAdContext } from "./context";
1+
import React from "react";
2+
import { View } from "react-native";
43

54
const Wrapper = (props) => {
6-
const [height, setHeight] = useState(0);
7-
const ref = useRef();
8-
const { nativeAd } = useContext(NativeAdContext);
9-
10-
useEffect(() => {
11-
setTimeout(() => {
12-
if (nativeAd && ref.current !== null) {
13-
ref.current?.scrollTo({
14-
x: 0,
15-
y: 1,
16-
animated: true,
17-
});
18-
}
19-
}, 1000);
20-
}, [nativeAd]);
21-
225
return (
23-
<ScrollView
6+
<View
247
{...props}
25-
ref={ref}
26-
onLayout={(event) => {
27-
props.onLayout?.(event);
28-
const height = event.nativeEvent.layout.height;
29-
setTimeout(() => setHeight(height));
30-
}}
31-
style={[
32-
{
33-
height: height === 0 ? "auto" : height,
34-
},
35-
styles.container,
36-
]}
37-
contentContainerStyle={{
38-
height: height === 0 ? "auto" : height + 1,
39-
}}
40-
scrollEnabled={false}
418
/>
429
);
4310
};
4411

4512
export default Wrapper;
46-
47-
const styles = StyleSheet.create({
48-
container: {
49-
backgroundColor: "transparent",
50-
},
51-
});

‎src/index.js

+5-9
Original file line numberDiff line numberDiff line change
@@ -83,17 +83,16 @@ export class NativeAdView extends Component {
8383
}
8484
};
8585

86-
_onAdLefApplication = (event) => {
86+
_onAdLeftApplication = (event) => {
8787
if (this.props.onAdLeftApplication)
8888
this.props.onAdLeftApplication(event.nativeEvent);
8989
};
9090

9191
updateAd() {
92-
if (this.componentMounted) {
93-
this.setState({
94-
nativeAd: this.ad,
95-
});
96-
}
92+
if (!this.componentMounted) return;
93+
this.setState({
94+
nativeAd: this.ad,
95+
});
9796
}
9897

9998
componentDidMount() {
@@ -154,9 +153,7 @@ export class NativeAdView extends Component {
154153
AdOptions.adChoicesPlacement[this.props.adChoicesPlacement]
155154
}
156155
>
157-
<AdBadge {...this.props.adBadgeProps} />
158156
<Wrapper
159-
160157
onLayout={(event) => {
161158
this.setState({
162159
nativeAdView: this.nativeAdRef,
@@ -186,5 +183,4 @@ NativeAdView.defaultProps = {
186183

187184
NativeAdView.simulatorId = "SIMULATOR";
188185

189-
190186
export default NativeAdView;

0 commit comments

Comments
 (0)
Please sign in to comment.