react-native-google-mobile-ads 14.7.1 → 14.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. package/README.md +86 -1
  2. package/android/build.gradle +10 -0
  3. package/android/src/main/java/io/invertase/googlemobileads/ReactNativeAppModule.java +2 -2
  4. package/android/src/main/java/io/invertase/googlemobileads/ReactNativeGoogleMobileAdsConsentModule.java +2 -2
  5. package/android/src/main/java/io/invertase/googlemobileads/ReactNativeGoogleMobileAdsMediaView.kt +57 -0
  6. package/android/src/main/java/io/invertase/googlemobileads/ReactNativeGoogleMobileAdsMediaViewManager.kt +55 -0
  7. package/android/src/main/java/io/invertase/googlemobileads/ReactNativeGoogleMobileAdsModule.kt +5 -4
  8. package/android/src/main/java/io/invertase/googlemobileads/ReactNativeGoogleMobileAdsNativeAdView.kt +107 -0
  9. package/android/src/main/java/io/invertase/googlemobileads/ReactNativeGoogleMobileAdsNativeAdViewManager.kt +85 -0
  10. package/android/src/main/java/io/invertase/googlemobileads/ReactNativeGoogleMobileAdsNativeModule.kt +211 -0
  11. package/android/src/main/java/io/invertase/googlemobileads/ReactNativeGoogleMobileAdsPackage.kt +102 -13
  12. package/android/src/oldarch/com/facebook/react/viewmanagers/RNGoogleMobileAdsMediaViewManagerDelegate.java +29 -0
  13. package/android/src/oldarch/com/facebook/react/viewmanagers/RNGoogleMobileAdsMediaViewManagerInterface.java +10 -0
  14. package/android/src/oldarch/com/facebook/react/viewmanagers/RNGoogleMobileAdsNativeViewManagerDelegate.java +33 -0
  15. package/android/src/oldarch/com/facebook/react/viewmanagers/RNGoogleMobileAdsNativeViewManagerInterface.java +10 -0
  16. package/android/src/oldarch/io/invertase/googlemobileads/NativeGoogleMobileAdsNativeModuleSpec.kt +18 -0
  17. package/docs/displaying-ads.mdx +4 -0
  18. package/docs/european-user-consent.mdx +2 -0
  19. package/docs/index.mdx +5 -4
  20. package/docs/native-ads.mdx +365 -0
  21. package/docs.json +1 -0
  22. package/ios/RNGoogleMobileAds/RNGoogleMobileAdsMediaView.h +49 -0
  23. package/ios/RNGoogleMobileAds/RNGoogleMobileAdsMediaView.mm +152 -0
  24. package/ios/RNGoogleMobileAds/RNGoogleMobileAdsNativeModule.h +35 -0
  25. package/ios/RNGoogleMobileAds/RNGoogleMobileAdsNativeModule.mm +290 -0
  26. package/ios/RNGoogleMobileAds/RNGoogleMobileAdsNativeView.h +48 -0
  27. package/ios/RNGoogleMobileAds/RNGoogleMobileAdsNativeView.mm +218 -0
  28. package/jest.setup.ts +7 -0
  29. package/lib/commonjs/NativeAdEventType.js +19 -0
  30. package/lib/commonjs/NativeAdEventType.js.map +1 -0
  31. package/lib/commonjs/TestIds.js +15 -8
  32. package/lib/commonjs/TestIds.js.map +1 -1
  33. package/lib/commonjs/ads/native-ad/NativeAd.js +122 -0
  34. package/lib/commonjs/ads/native-ad/NativeAd.js.map +1 -0
  35. package/lib/commonjs/ads/native-ad/NativeAdContext.js +26 -0
  36. package/lib/commonjs/ads/native-ad/NativeAdContext.js.map +1 -0
  37. package/lib/commonjs/ads/native-ad/NativeAdView.js +48 -0
  38. package/lib/commonjs/ads/native-ad/NativeAdView.js.map +1 -0
  39. package/lib/commonjs/ads/native-ad/NativeAsset.js +71 -0
  40. package/lib/commonjs/ads/native-ad/NativeAsset.js.map +1 -0
  41. package/lib/commonjs/ads/native-ad/NativeMediaView.js +58 -0
  42. package/lib/commonjs/ads/native-ad/NativeMediaView.js.map +1 -0
  43. package/lib/commonjs/common/ref.js +45 -0
  44. package/lib/commonjs/common/ref.js.map +1 -0
  45. package/lib/commonjs/index.js +47 -0
  46. package/lib/commonjs/index.js.map +1 -1
  47. package/lib/commonjs/specs/components/GoogleMobileAdsBannerViewNativeComponent.js +17 -0
  48. package/lib/commonjs/specs/components/GoogleMobileAdsBannerViewNativeComponent.js.map +1 -1
  49. package/lib/commonjs/specs/components/GoogleMobileAdsMediaViewNativeComponent.js +26 -0
  50. package/lib/commonjs/specs/components/GoogleMobileAdsMediaViewNativeComponent.js.map +1 -0
  51. package/lib/commonjs/specs/components/GoogleMobileAdsNativeViewNativeComponent.js +31 -0
  52. package/lib/commonjs/specs/components/GoogleMobileAdsNativeViewNativeComponent.js.map +1 -0
  53. package/lib/commonjs/specs/modules/NativeConsentModule.js.map +1 -1
  54. package/lib/commonjs/specs/modules/NativeGoogleMobileAdsModule.js +1 -1
  55. package/lib/commonjs/specs/modules/NativeGoogleMobileAdsNativeModule.js +25 -0
  56. package/lib/commonjs/specs/modules/NativeGoogleMobileAdsNativeModule.js.map +1 -0
  57. package/lib/commonjs/types/NativeAdRequestOptions.js +37 -0
  58. package/lib/commonjs/types/NativeAdRequestOptions.js.map +1 -0
  59. package/lib/commonjs/types/index.js +11 -0
  60. package/lib/commonjs/types/index.js.map +1 -1
  61. package/lib/commonjs/version.js +1 -1
  62. package/lib/module/NativeAdEventType.js +13 -0
  63. package/lib/module/NativeAdEventType.js.map +1 -0
  64. package/lib/module/TestIds.js +15 -8
  65. package/lib/module/TestIds.js.map +1 -1
  66. package/lib/module/ads/native-ad/NativeAd.js +115 -0
  67. package/lib/module/ads/native-ad/NativeAd.js.map +1 -0
  68. package/lib/module/ads/native-ad/NativeAdContext.js +20 -0
  69. package/lib/module/ads/native-ad/NativeAdContext.js.map +1 -0
  70. package/lib/module/ads/native-ad/NativeAdView.js +40 -0
  71. package/lib/module/ads/native-ad/NativeAdView.js.map +1 -0
  72. package/lib/module/ads/native-ad/NativeAsset.js +63 -0
  73. package/lib/module/ads/native-ad/NativeAsset.js.map +1 -0
  74. package/lib/module/ads/native-ad/NativeMediaView.js +50 -0
  75. package/lib/module/ads/native-ad/NativeMediaView.js.map +1 -0
  76. package/lib/module/common/ref.js +38 -0
  77. package/lib/module/common/ref.js.map +1 -0
  78. package/lib/module/index.js +5 -0
  79. package/lib/module/index.js.map +1 -1
  80. package/lib/module/specs/components/GoogleMobileAdsBannerViewNativeComponent.js +17 -0
  81. package/lib/module/specs/components/GoogleMobileAdsBannerViewNativeComponent.js.map +1 -1
  82. package/lib/module/specs/components/GoogleMobileAdsMediaViewNativeComponent.js +20 -0
  83. package/lib/module/specs/components/GoogleMobileAdsMediaViewNativeComponent.js.map +1 -0
  84. package/lib/module/specs/components/GoogleMobileAdsNativeViewNativeComponent.js +24 -0
  85. package/lib/module/specs/components/GoogleMobileAdsNativeViewNativeComponent.js.map +1 -0
  86. package/lib/module/specs/modules/NativeConsentModule.js.map +1 -1
  87. package/lib/module/specs/modules/NativeGoogleMobileAdsModule.js +1 -1
  88. package/lib/module/specs/modules/NativeGoogleMobileAdsNativeModule.js +20 -0
  89. package/lib/module/specs/modules/NativeGoogleMobileAdsNativeModule.js.map +1 -0
  90. package/lib/module/types/NativeAdRequestOptions.js +32 -0
  91. package/lib/module/types/NativeAdRequestOptions.js.map +1 -0
  92. package/lib/module/types/index.js +1 -0
  93. package/lib/module/types/index.js.map +1 -1
  94. package/lib/module/version.js +1 -1
  95. package/lib/typescript/NativeAdEventType.d.ts +39 -0
  96. package/lib/typescript/NativeAdEventType.d.ts.map +1 -0
  97. package/lib/typescript/TestIds.d.ts +3 -0
  98. package/lib/typescript/TestIds.d.ts.map +1 -1
  99. package/lib/typescript/ads/native-ad/NativeAd.d.ts +46 -0
  100. package/lib/typescript/ads/native-ad/NativeAd.d.ts.map +1 -0
  101. package/lib/typescript/ads/native-ad/NativeAdContext.d.ts +10 -0
  102. package/lib/typescript/ads/native-ad/NativeAdContext.d.ts.map +1 -0
  103. package/lib/typescript/ads/native-ad/NativeAdView.d.ts +8 -0
  104. package/lib/typescript/ads/native-ad/NativeAdView.d.ts.map +1 -0
  105. package/lib/typescript/ads/native-ad/NativeAsset.d.ts +18 -0
  106. package/lib/typescript/ads/native-ad/NativeAsset.d.ts.map +1 -0
  107. package/lib/typescript/ads/native-ad/NativeMediaView.d.ts +7 -0
  108. package/lib/typescript/ads/native-ad/NativeMediaView.d.ts.map +1 -0
  109. package/lib/typescript/common/ref.d.ts +13 -0
  110. package/lib/typescript/common/ref.d.ts.map +1 -0
  111. package/lib/typescript/index.d.ts +6 -1
  112. package/lib/typescript/index.d.ts.map +1 -1
  113. package/lib/typescript/specs/components/GoogleMobileAdsBannerViewNativeComponent.d.ts.map +1 -1
  114. package/lib/typescript/specs/components/GoogleMobileAdsMediaViewNativeComponent.d.ts +9 -0
  115. package/lib/typescript/specs/components/GoogleMobileAdsMediaViewNativeComponent.d.ts.map +1 -0
  116. package/lib/typescript/specs/components/GoogleMobileAdsNativeViewNativeComponent.d.ts +14 -0
  117. package/lib/typescript/specs/components/GoogleMobileAdsNativeViewNativeComponent.d.ts.map +1 -0
  118. package/lib/typescript/specs/modules/NativeConsentModule.d.ts +3 -4
  119. package/lib/typescript/specs/modules/NativeConsentModule.d.ts.map +1 -1
  120. package/lib/typescript/specs/modules/NativeGoogleMobileAdsModule.d.ts +1 -17
  121. package/lib/typescript/specs/modules/NativeGoogleMobileAdsModule.d.ts.map +1 -1
  122. package/lib/typescript/specs/modules/NativeGoogleMobileAdsNativeModule.d.ts +37 -0
  123. package/lib/typescript/specs/modules/NativeGoogleMobileAdsNativeModule.d.ts.map +1 -0
  124. package/lib/typescript/types/NativeAdRequestOptions.d.ts +36 -0
  125. package/lib/typescript/types/NativeAdRequestOptions.d.ts.map +1 -0
  126. package/lib/typescript/types/index.d.ts +1 -0
  127. package/lib/typescript/types/index.d.ts.map +1 -1
  128. package/lib/typescript/version.d.ts +1 -1
  129. package/package.json +1 -1
  130. package/src/NativeAdEventType.ts +46 -0
  131. package/src/TestIds.ts +13 -6
  132. package/src/ads/native-ad/NativeAd.ts +152 -0
  133. package/src/ads/native-ad/NativeAdContext.ts +26 -0
  134. package/src/ads/native-ad/NativeAdView.tsx +43 -0
  135. package/src/ads/native-ad/NativeAsset.tsx +66 -0
  136. package/src/ads/native-ad/NativeMediaView.tsx +44 -0
  137. package/src/common/ref.ts +44 -0
  138. package/src/index.ts +5 -0
  139. package/src/specs/components/GoogleMobileAdsBannerViewNativeComponent.ts +17 -0
  140. package/src/specs/components/GoogleMobileAdsMediaViewNativeComponent.ts +30 -0
  141. package/src/specs/components/GoogleMobileAdsNativeViewNativeComponent.ts +44 -0
  142. package/src/specs/modules/NativeConsentModule.ts +3 -4
  143. package/src/specs/modules/NativeGoogleMobileAdsModule.ts +2 -2
  144. package/src/specs/modules/NativeGoogleMobileAdsNativeModule.ts +64 -0
  145. package/src/types/NativeAdRequestOptions.ts +55 -0
  146. package/src/types/index.ts +1 -0
  147. package/src/version.ts +1 -1
@@ -0,0 +1,290 @@
1
+ /**
2
+ * Copyright (c) 2016-present Invertase Limited & Contributors
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this library except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ *
16
+ */
17
+
18
+ #if !TARGET_OS_MACCATALYST
19
+
20
+ #import "RNGoogleMobileAdsNativeModule.h"
21
+ #import "RNGoogleMobileAdsCommon.h"
22
+
23
+ typedef void (^RNGMANativeAdLoadCompletionHandler)(GADNativeAd *_Nullable nativeAd,
24
+ NSError *_Nullable error);
25
+
26
+ @interface RNGMANativeAdHolder
27
+ : NSObject <GADNativeAdLoaderDelegate, GADNativeAdDelegate, GADVideoControllerDelegate>
28
+
29
+ @property(strong, nullable) GADNativeAd *nativeAd;
30
+
31
+ - (instancetype)initWithNativeModule:(RNGoogleMobileAdsNativeModule *)nativeModule
32
+ adUnitId:(NSString *)adUnitId
33
+ requestOptions:(NSDictionary *)requestOptions;
34
+
35
+ - (void)loadWithCompletionHandler:(RNGMANativeAdLoadCompletionHandler)completionHandler;
36
+
37
+ - (void)dispose;
38
+
39
+ @end
40
+
41
+ @implementation RNGoogleMobileAdsNativeModule {
42
+ NSMutableDictionary<NSString *, RNGMANativeAdHolder *> *_adHolders;
43
+ }
44
+
45
+ RCT_EXPORT_MODULE();
46
+
47
+ - (dispatch_queue_t)methodQueue {
48
+ return dispatch_get_main_queue();
49
+ }
50
+
51
+ #ifdef RCT_NEW_ARCH_ENABLED
52
+ - (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
53
+ (const facebook::react::ObjCTurboModule::InitParams &)params {
54
+ return std::make_shared<facebook::react::NativeGoogleMobileAdsNativeModuleSpecJSI>(params);
55
+ }
56
+ #else
57
+ - (NSArray<NSString *> *)supportedEvents {
58
+ return @[ @"RNGMANativeAdEvent" ];
59
+ }
60
+ #endif
61
+
62
+ - (instancetype)init {
63
+ if (self = [super init]) {
64
+ _adHolders = [NSMutableDictionary dictionary];
65
+ }
66
+ return self;
67
+ }
68
+
69
+ RCT_EXPORT_METHOD(
70
+ load
71
+ : (NSString *)adUnitId requestOptions
72
+ : (NSDictionary *)requestOptions resolve
73
+ : (RCTPromiseResolveBlock)resolve reject
74
+ : (RCTPromiseRejectBlock)reject {
75
+ RNGMANativeAdHolder *adHolder =
76
+ [[RNGMANativeAdHolder alloc] initWithNativeModule:self
77
+ adUnitId:adUnitId
78
+ requestOptions:requestOptions];
79
+
80
+ [adHolder loadWithCompletionHandler:^(GADNativeAd *nativeAd, NSError *error) {
81
+ if (error != nil) {
82
+ reject(@"ERROR_LOAD", error.description, error);
83
+ return;
84
+ }
85
+
86
+ NSString *responseId = nativeAd.responseInfo.responseIdentifier;
87
+ [_adHolders setValue:adHolder forKey:responseId];
88
+
89
+ resolve(@{
90
+ @"responseId" : responseId,
91
+ @"advertiser" : nativeAd.advertiser ?: [NSNull null],
92
+ @"body" : nativeAd.body ?: [NSNull null],
93
+ @"callToAction" : nativeAd.callToAction ?: [NSNull null],
94
+ @"headline" : nativeAd.headline ?: [NSNull null],
95
+ @"price" : nativeAd.price ?: [NSNull null],
96
+ @"store" : nativeAd.store ?: [NSNull null],
97
+ @"starRating" : nativeAd.starRating ?: [NSNull null],
98
+ @"icon" : nativeAd.icon != nil
99
+ ? @{@"scale" : @(nativeAd.icon.scale), @"url" : nativeAd.icon.imageURL.absoluteString}
100
+ : [NSNull null],
101
+ @"mediaContent" : @{
102
+ @"aspectRatio" : @(nativeAd.mediaContent.aspectRatio),
103
+ @"hasVideoContent" : @(nativeAd.mediaContent.hasVideoContent),
104
+ @"duration" : @(nativeAd.mediaContent.duration)
105
+ }
106
+ });
107
+ }];
108
+ })
109
+
110
+ RCT_EXPORT_METHOD(destroy
111
+ : (NSString *)responseId {
112
+ [[_adHolders valueForKey:responseId] dispose];
113
+ [_adHolders removeObjectForKey:responseId];
114
+ });
115
+
116
+ - (GADNativeAd *)nativeAdForResponseId:(NSString *)responseId {
117
+ return [_adHolders valueForKey:responseId].nativeAd;
118
+ }
119
+
120
+ - (void)dealloc {
121
+ NSArray *adHolders = [_adHolders allValues];
122
+ for (RNGMANativeAdHolder *adHolder in adHolders) {
123
+ [adHolder dispose];
124
+ }
125
+ [_adHolders removeAllObjects];
126
+ }
127
+
128
+ @end
129
+
130
+ #pragma mark - RNGMANativeAdHolder
131
+
132
+ @implementation RNGMANativeAdHolder {
133
+ __weak RNGoogleMobileAdsNativeModule *_nativeModule;
134
+ GADAdLoader *_adLoader;
135
+ GAMRequest *_adRequest;
136
+ RNGMANativeAdLoadCompletionHandler _completionHandler;
137
+ }
138
+
139
+ - (instancetype)initWithNativeModule:(RNGoogleMobileAdsNativeModule *)nativeModule
140
+ adUnitId:(NSString *)adUnitId
141
+ requestOptions:(NSDictionary *)requestOptions {
142
+ if (self = [super init]) {
143
+ _nativeModule = nativeModule;
144
+
145
+ GADNativeAdImageAdLoaderOptions *imageOptions = [[GADNativeAdImageAdLoaderOptions alloc] init];
146
+ // imageOptions.disableImageLoading = YES;
147
+ GADNativeAdMediaAdLoaderOptions *mediaOptions = [[GADNativeAdMediaAdLoaderOptions alloc] init];
148
+ if (requestOptions[@"aspectRatio"]) {
149
+ switch ([requestOptions[@"aspectRatio"] intValue]) {
150
+ case 1:
151
+ mediaOptions.mediaAspectRatio = GADMediaAspectRatioAny;
152
+ break;
153
+ case 2:
154
+ mediaOptions.mediaAspectRatio = GADMediaAspectRatioLandscape;
155
+ break;
156
+ case 3:
157
+ mediaOptions.mediaAspectRatio = GADMediaAspectRatioPortrait;
158
+ break;
159
+ case 4:
160
+ mediaOptions.mediaAspectRatio = GADMediaAspectRatioSquare;
161
+ break;
162
+ }
163
+ }
164
+ GADNativeAdViewAdOptions *adViewOptions = [[GADNativeAdViewAdOptions alloc] init];
165
+ if (requestOptions[@"aspectRatio"]) {
166
+ switch ([requestOptions[@"aspectRatio"] intValue]) {
167
+ case 0:
168
+ adViewOptions.preferredAdChoicesPosition = GADAdChoicesPositionTopLeftCorner;
169
+ break;
170
+ case 1:
171
+ adViewOptions.preferredAdChoicesPosition = GADAdChoicesPositionTopRightCorner;
172
+ break;
173
+ case 2:
174
+ adViewOptions.preferredAdChoicesPosition = GADAdChoicesPositionBottomRightCorner;
175
+ break;
176
+ case 3:
177
+ adViewOptions.preferredAdChoicesPosition = GADAdChoicesPositionBottomLeftCorner;
178
+ break;
179
+ }
180
+ }
181
+ GADVideoOptions *videoOptions = [[GADVideoOptions alloc] init];
182
+ if (requestOptions[@"startVideoMuted"]) {
183
+ videoOptions.startMuted = [requestOptions[@"startVideoMuted"] boolValue];
184
+ }
185
+
186
+ _adLoader = [[GADAdLoader alloc]
187
+ initWithAdUnitID:adUnitId
188
+ rootViewController:[RNGoogleMobileAdsCommon currentViewController]
189
+ adTypes:@[ GADAdLoaderAdTypeNative ]
190
+ options:@[ imageOptions, mediaOptions, adViewOptions, videoOptions ]];
191
+ _adLoader.delegate = self;
192
+ _adRequest = [RNGoogleMobileAdsCommon buildAdRequest:requestOptions];
193
+ }
194
+ return self;
195
+ }
196
+
197
+ - (void)loadWithCompletionHandler:(RNGMANativeAdLoadCompletionHandler)completionHandler {
198
+ _completionHandler = completionHandler;
199
+ [_adLoader loadRequest:_adRequest];
200
+ }
201
+
202
+ - (void)dispose {
203
+ _nativeAd = nil;
204
+ _nativeModule = nil;
205
+ _adLoader = nil;
206
+ _adRequest = nil;
207
+ _completionHandler = nil;
208
+ }
209
+
210
+ #pragma mark - GADNativeAdLoaderDelegate
211
+
212
+ - (void)adLoader:(nonnull GADAdLoader *)adLoader
213
+ didReceiveNativeAd:(nonnull GADNativeAd *)nativeAd {
214
+ _nativeAd = nativeAd;
215
+ _nativeAd.delegate = self;
216
+ if (nativeAd.mediaContent.hasVideoContent) {
217
+ nativeAd.mediaContent.videoController.delegate = self;
218
+ }
219
+ _completionHandler(nativeAd, nil);
220
+ _completionHandler = nil;
221
+ }
222
+
223
+ - (void)adLoader:(nonnull GADAdLoader *)adLoader
224
+ didFailToReceiveAdWithError:(nonnull NSError *)error {
225
+ _completionHandler(nil, error);
226
+ _completionHandler = nil;
227
+ }
228
+
229
+ #pragma mark - GADNativeAdDelegate
230
+
231
+ - (void)nativeAdDidRecordImpression:(GADNativeAd *)nativeAd {
232
+ [self emitAdEvent:@"impression"];
233
+ }
234
+
235
+ - (void)nativeAdDidRecordClick:(GADNativeAd *)nativeAd {
236
+ [self emitAdEvent:@"clicked"];
237
+ }
238
+
239
+ - (void)nativeAdWillPresentScreen:(GADNativeAd *)nativeAd {
240
+ [self emitAdEvent:@"opened"];
241
+ }
242
+
243
+ - (void)nativeAdWillDismissScreen:(GADNativeAd *)nativeAd {
244
+ // Not in use
245
+ }
246
+
247
+ - (void)nativeAdDidDismissScreen:(GADNativeAd *)nativeAd {
248
+ [self emitAdEvent:@"closed"];
249
+ }
250
+
251
+ - (void)nativeAdWillLeaveApplication:(GADNativeAd *)nativeAd {
252
+ // Not in use
253
+ }
254
+
255
+ - (void)videoControllerDidPlayVideo:(nonnull GADVideoController *)videoController {
256
+ [self emitAdEvent:@"video_played"];
257
+ }
258
+
259
+ - (void)videoControllerDidPauseVideo:(nonnull GADVideoController *)videoController {
260
+ [self emitAdEvent:@"video_paused"];
261
+ }
262
+
263
+ - (void)videoControllerDidEndVideoPlayback:(nonnull GADVideoController *)videoController {
264
+ [self emitAdEvent:@"video_ended"];
265
+ }
266
+
267
+ - (void)videoControllerDidMuteVideo:(nonnull GADVideoController *)videoController {
268
+ [self emitAdEvent:@"video_muted"];
269
+ }
270
+
271
+ - (void)videoControllerDidUnmuteVideo:(nonnull GADVideoController *)videoController {
272
+ [self emitAdEvent:@"video_unmuted"];
273
+ }
274
+
275
+ - (void)emitAdEvent:(NSString *)type {
276
+ if (_nativeModule == nil || _nativeAd == nil) {
277
+ return;
278
+ }
279
+ NSDictionary *payload =
280
+ @{@"responseId" : _nativeAd.responseInfo.responseIdentifier, @"type" : type};
281
+ #ifdef RCT_NEW_ARCH_ENABLED
282
+ [_nativeModule emitOnAdEvent:payload];
283
+ #else
284
+ [_nativeModule sendEventWithName:@"RNGMANativeAdEvent" body:payload];
285
+ #endif
286
+ }
287
+
288
+ @end
289
+
290
+ #endif
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Copyright (c) 2016-present Invertase Limited & Contributors
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this library except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ *
16
+ */
17
+
18
+ #import <GoogleMobileAds/GADNativeAd.h>
19
+ #import <React/RCTBridge.h>
20
+ #import <React/RCTUIManager.h>
21
+
22
+ #ifdef RCT_NEW_ARCH_ENABLED
23
+ #import <React/RCTViewComponentView.h>
24
+ #else
25
+ #import <React/RCTView.h>
26
+ #endif
27
+
28
+ NS_ASSUME_NONNULL_BEGIN
29
+
30
+ #ifdef RCT_NEW_ARCH_ENABLED
31
+ @interface RNGoogleMobileAdsNativeView : RCTViewComponentView
32
+
33
+ @property(nonatomic, strong, nullable) GADNativeAdView *contentView;
34
+ #else
35
+ @interface RNGoogleMobileAdsNativeView : GADNativeAdView
36
+
37
+ - (instancetype)initWithBridge:(RCTBridge *)bridge;
38
+ #endif
39
+
40
+ @property(nonatomic, copy) NSString *responseId;
41
+
42
+ @end
43
+
44
+ @interface RNGoogleMobileAdsNativeViewManager : RCTViewManager
45
+
46
+ @end
47
+
48
+ NS_ASSUME_NONNULL_END
@@ -0,0 +1,218 @@
1
+ /**
2
+ * Copyright (c) 2016-present Invertase Limited & Contributors
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this library except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ *
16
+ */
17
+
18
+ #import "RNGoogleMobileAdsNativeView.h"
19
+ #import "RNGoogleMobileAdsMediaView.h"
20
+ #import "RNGoogleMobileAdsNativeModule.h"
21
+
22
+ #ifdef RCT_NEW_ARCH_ENABLED
23
+ #import <react/renderer/components/RNGoogleMobileAdsSpec/ComponentDescriptors.h>
24
+ #import <react/renderer/components/RNGoogleMobileAdsSpec/EventEmitters.h>
25
+ #import <react/renderer/components/RNGoogleMobileAdsSpec/Props.h>
26
+ #import <react/renderer/components/RNGoogleMobileAdsSpec/RCTComponentViewHelpers.h>
27
+
28
+ #import "RCTFabricComponentsPlugins.h"
29
+ #endif
30
+
31
+ @interface RCTBridge (Private)
32
+ + (RCTBridge *)currentBridge;
33
+ @end
34
+
35
+ #ifdef RCT_NEW_ARCH_ENABLED
36
+ using namespace facebook::react;
37
+
38
+ @interface RNGoogleMobileAdsNativeView () <RCTRNGoogleMobileAdsNativeViewViewProtocol>
39
+ @end
40
+ #endif
41
+
42
+ @implementation RNGoogleMobileAdsNativeView {
43
+ __weak RCTBridge *_bridge;
44
+ __weak RNGoogleMobileAdsNativeModule *_nativeModule;
45
+ __weak GADNativeAd *_nativeAd;
46
+ GADNativeAdView *_nativeAdView;
47
+ dispatch_block_t _debouncedReload;
48
+ }
49
+
50
+ #ifdef RCT_NEW_ARCH_ENABLED
51
+ #pragma mark - Fabric specific
52
+
53
+ - (instancetype)initWithFrame:(CGRect)frame {
54
+ if (self = [super initWithFrame:frame]) {
55
+ static const auto defaultProps = std::make_shared<const RNGoogleMobileAdsBannerViewProps>();
56
+ _props = defaultProps;
57
+
58
+ _bridge = [RCTBridge currentBridge];
59
+ _nativeModule = [_bridge moduleForClass:RNGoogleMobileAdsNativeModule.class];
60
+ _nativeAdView = [[GADNativeAdView alloc] init];
61
+ self.contentView = _nativeAdView;
62
+ }
63
+
64
+ return self;
65
+ }
66
+
67
+ #pragma mark - RCTComponentViewProtocol
68
+
69
+ + (ComponentDescriptorProvider)componentDescriptorProvider {
70
+ return concreteComponentDescriptorProvider<RNGoogleMobileAdsNativeViewComponentDescriptor>();
71
+ }
72
+
73
+ + (BOOL)shouldBeRecycled {
74
+ return NO;
75
+ }
76
+
77
+ - (void)mountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView
78
+ index:(NSInteger)index {
79
+ [_nativeAdView insertSubview:childComponentView atIndex:index];
80
+ }
81
+
82
+ - (void)unmountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView
83
+ index:(NSInteger)index {
84
+ [childComponentView removeFromSuperview];
85
+ }
86
+
87
+ - (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps {
88
+ const auto &oldViewProps =
89
+ *std::static_pointer_cast<RNGoogleMobileAdsNativeViewProps const>(_props);
90
+ const auto &newViewProps =
91
+ *std::static_pointer_cast<RNGoogleMobileAdsNativeViewProps const>(props);
92
+
93
+ if (oldViewProps.responseId != newViewProps.responseId) {
94
+ NSString *responseId = [[NSString alloc] initWithUTF8String:newViewProps.responseId.c_str()];
95
+ [self setResponseId:responseId];
96
+ }
97
+
98
+ [super updateProps:props oldProps:oldProps];
99
+ }
100
+
101
+ - (void)handleCommand:(const NSString *)commandName args:(const NSArray *)args {
102
+ RCTRNGoogleMobileAdsNativeViewHandleCommand(self, commandName, args);
103
+ }
104
+
105
+ #else
106
+ #pragma mark - Paper specific
107
+
108
+ - (instancetype)initWithBridge:(RCTBridge *)bridge {
109
+ if (self = [super init]) {
110
+ _bridge = bridge;
111
+ _nativeModule = [_bridge moduleForClass:RNGoogleMobileAdsNativeModule.class];
112
+ _nativeAdView = self;
113
+ }
114
+ return self;
115
+ }
116
+
117
+ #endif // RCT_NEW_ARCH_ENABLED
118
+
119
+ #pragma mark - Common logics
120
+
121
+ - (void)setResponseId:(NSString *)responseId {
122
+ _responseId = responseId;
123
+ _nativeAd = [_nativeModule nativeAdForResponseId:responseId];
124
+ [self reloadAd];
125
+ }
126
+
127
+ - (void)registerAsset:(NSString *)assetType reactTag:(NSInteger)reactTag {
128
+ RCTExecuteOnMainQueue(^{
129
+ UIView *view = [_bridge.uiManager viewForReactTag:@(reactTag)];
130
+
131
+ if ([assetType isEqual:@"media"] && [view isKindOfClass:RNGoogleMobileAdsMediaView.class]) {
132
+ #ifdef RCT_NEW_ARCH_ENABLED
133
+ GADMediaView *mediaView = ((RNGoogleMobileAdsMediaView *)view).contentView;
134
+ #else
135
+ GADMediaView *mediaView = (RNGoogleMobileAdsMediaView *) view;
136
+ #endif
137
+ [_nativeAdView setMediaView:mediaView];
138
+ [self reloadAd];
139
+ return;
140
+ }
141
+
142
+ NSDictionary *viewMappings = @{
143
+ @"advertiser" : @"advertiserView",
144
+ @"body" : @"bodyView",
145
+ @"callToAction" : @"callToActionView",
146
+ @"headline" : @"headlineView",
147
+ @"price" : @"priceView",
148
+ @"store" : @"storeView",
149
+ @"starRating" : @"starRatingView",
150
+ @"icon" : @"iconView",
151
+ @"image" : @"imageView",
152
+ };
153
+ NSString *property = viewMappings[assetType];
154
+ if (property) {
155
+ view.userInteractionEnabled = NO;
156
+ [_nativeAdView setValue:view forKey:property];
157
+ [self reloadAd];
158
+ }
159
+ });
160
+ }
161
+
162
+ - (void)reloadAd {
163
+ if (_debouncedReload != nil) {
164
+ dispatch_block_cancel(_debouncedReload);
165
+ }
166
+ _debouncedReload = dispatch_block_create(DISPATCH_BLOCK_NO_QOS_CLASS, ^{
167
+ if (_nativeAd != nil) {
168
+ _nativeAdView.nativeAd = _nativeAd;
169
+ }
170
+ });
171
+ dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, 0.1 * NSEC_PER_SEC);
172
+ dispatch_after(time, dispatch_get_main_queue(), _debouncedReload);
173
+ }
174
+
175
+ - (void)dealloc {
176
+ _nativeAdView = nil;
177
+ if (_debouncedReload != nil) {
178
+ dispatch_block_cancel(_debouncedReload);
179
+ _debouncedReload = nil;
180
+ }
181
+ }
182
+
183
+ @end
184
+
185
+ @implementation RNGoogleMobileAdsNativeViewManager
186
+
187
+ RCT_EXPORT_MODULE(RNGoogleMobileAdsNativeView)
188
+
189
+ RCT_EXPORT_VIEW_PROPERTY(responseId, NSString)
190
+
191
+ #ifndef RCT_NEW_ARCH_ENABLED
192
+ - (UIView *)view {
193
+ return [[RNGoogleMobileAdsNativeView alloc] initWithBridge:self.bridge];
194
+ }
195
+
196
+ RCT_EXPORT_METHOD(registerAsset
197
+ : (nonnull NSNumber *)reactTag commandID
198
+ : (NSInteger)commandID commandArgs
199
+ : (NSArray<id> *)commandArgs) {
200
+ [self.bridge.uiManager
201
+ addUIBlock:^(RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
202
+ RNGoogleMobileAdsNativeView *view = viewRegistry[reactTag];
203
+ if (!view || ![view isKindOfClass:[RNGoogleMobileAdsNativeView class]]) {
204
+ RCTLogError(@"Cannot find NativeView with tag #%@", reactTag);
205
+ return;
206
+ }
207
+ [view registerAsset:commandArgs[0] reactTag:((NSNumber *)commandArgs[1]).intValue];
208
+ }];
209
+ }
210
+ #endif
211
+
212
+ @end
213
+
214
+ #ifdef RCT_NEW_ARCH_ENABLED
215
+ Class<RCTComponentViewProtocol> RNGoogleMobileAdsNativeViewCls(void) {
216
+ return RNGoogleMobileAdsNativeView.class;
217
+ }
218
+ #endif
package/jest.setup.ts CHANGED
@@ -50,3 +50,10 @@ jest.doMock('./src/specs/components/GoogleMobileAdsBannerViewNativeComponent', (
50
50
  default: ReactNative.View,
51
51
  };
52
52
  });
53
+ jest.doMock('./src/specs/components/GoogleMobileAdsNativeViewNativeComponent', () => {
54
+ return {
55
+ __esModule: true,
56
+ Commands: {},
57
+ default: ReactNative.View,
58
+ };
59
+ });
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.NativeAdEventType = void 0;
7
+ let NativeAdEventType = exports.NativeAdEventType = /*#__PURE__*/function (NativeAdEventType) {
8
+ NativeAdEventType["IMPRESSION"] = "impression";
9
+ NativeAdEventType["CLICKED"] = "clicked";
10
+ NativeAdEventType["OPENED"] = "opened";
11
+ NativeAdEventType["CLOSED"] = "closed";
12
+ NativeAdEventType["VIDEO_PLAYED"] = "video_played";
13
+ NativeAdEventType["VIDEO_PAUSED"] = "video_paused";
14
+ NativeAdEventType["VIDEO_ENDED"] = "video_ended";
15
+ NativeAdEventType["VIDEO_MUTED"] = "video_muted";
16
+ NativeAdEventType["VIDEO_UNMUTED"] = "video_unmuted";
17
+ return NativeAdEventType;
18
+ }({});
19
+ //# sourceMappingURL=NativeAdEventType.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["NativeAdEventType","exports"],"sourceRoot":"../../src","sources":["NativeAdEventType.ts"],"mappings":";;;;;;IAAYA,iBAAiB,GAAAC,OAAA,CAAAD,iBAAA,0BAAjBA,iBAAiB;EAAjBA,iBAAiB;EAAjBA,iBAAiB;EAAjBA,iBAAiB;EAAjBA,iBAAiB;EAAjBA,iBAAiB;EAAjBA,iBAAiB;EAAjBA,iBAAiB;EAAjBA,iBAAiB;EAAjBA,iBAAiB;EAAA,OAAjBA,iBAAiB;AAAA","ignoreList":[]}
@@ -29,12 +29,15 @@ const TestIds = exports.TestIds = {
29
29
  INTERSTITIAL: '',
30
30
  REWARDED: '',
31
31
  REWARDED_INTERSTITIAL: '',
32
- GAM_APP_OPEN: '/6499/example/app-open',
33
- GAM_BANNER: '/6499/example/banner',
34
- GAM_INTERSTITIAL: '/6499/example/interstitial',
35
- GAM_REWARDED: '/6499/example/rewarded',
36
- GAM_REWARDED_INTERSTITIAL: '/21775744923/example/rewarded_interstitial',
37
- GAM_NATIVE: '/6499/example/native',
32
+ NATIVE: '',
33
+ NATIVE_VIDEO: '',
34
+ GAM_APP_OPEN: '/21775744923/example/app-open',
35
+ GAM_BANNER: '/21775744923/example/fixed-size-banner',
36
+ GAM_INTERSTITIAL: '/21775744923/example/interstitial',
37
+ GAM_REWARDED: '/21775744923/example/rewarded',
38
+ GAM_REWARDED_INTERSTITIAL: '/21775744923/example/rewarded-interstitial',
39
+ GAM_NATIVE: '/21775744923/example/native',
40
+ GAM_NATIVE_VIDEO: '/21775744923/example/native-video',
38
41
  ..._reactNative.Platform.select({
39
42
  android: {
40
43
  APP_OPEN: 'ca-app-pub-3940256099942544/9257395921',
@@ -43,7 +46,9 @@ const TestIds = exports.TestIds = {
43
46
  INTERSTITIAL: 'ca-app-pub-3940256099942544/1033173712',
44
47
  INTERSTITIAL_VIDEO: 'ca-app-pub-3940256099942544/8691691433',
45
48
  REWARDED: 'ca-app-pub-3940256099942544/5224354917',
46
- REWARDED_INTERSTITIAL: 'ca-app-pub-3940256099942544/5354046379'
49
+ REWARDED_INTERSTITIAL: 'ca-app-pub-3940256099942544/5354046379',
50
+ NATIVE: 'ca-app-pub-3940256099942544/2247696110',
51
+ NATIVE_VIDEO: 'ca-app-pub-3940256099942544/1044960115'
47
52
  },
48
53
  ios: {
49
54
  APP_OPEN: 'ca-app-pub-3940256099942544/5575463023',
@@ -52,7 +57,9 @@ const TestIds = exports.TestIds = {
52
57
  INTERSTITIAL: 'ca-app-pub-3940256099942544/4411468910',
53
58
  INTERSTITIAL_VIDEO: 'ca-app-pub-3940256099942544/5135589807',
54
59
  REWARDED: 'ca-app-pub-3940256099942544/1712485313',
55
- REWARDED_INTERSTITIAL: 'ca-app-pub-3940256099942544/6978759866'
60
+ REWARDED_INTERSTITIAL: 'ca-app-pub-3940256099942544/6978759866',
61
+ NATIVE: 'ca-app-pub-3940256099942544/3986624511',
62
+ NATIVE_VIDEO: 'ca-app-pub-3940256099942544/2521693316'
56
63
  }
57
64
  })
58
65
  };
@@ -1 +1 @@
1
- {"version":3,"names":["_reactNative","require","TestIds","exports","APP_OPEN","ADAPTIVE_BANNER","BANNER","INTERSTITIAL","REWARDED","REWARDED_INTERSTITIAL","GAM_APP_OPEN","GAM_BANNER","GAM_INTERSTITIAL","GAM_REWARDED","GAM_REWARDED_INTERSTITIAL","GAM_NATIVE","Platform","select","android","INTERSTITIAL_VIDEO","ios"],"sourceRoot":"../../src","sources":["TestIds.ts"],"mappings":";;;;;;AAiBA,IAAAA,YAAA,GAAAC,OAAA;AAjBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAIO,MAAMC,OAAO,GAAAC,OAAA,CAAAD,OAAA,GAAG;EACrBE,QAAQ,EAAE,EAAE;EACZC,eAAe,EAAE,EAAE;EACnBC,MAAM,EAAE,EAAE;EACVC,YAAY,EAAE,EAAE;EAChBC,QAAQ,EAAE,EAAE;EACZC,qBAAqB,EAAE,EAAE;EACzBC,YAAY,EAAE,wBAAwB;EACtCC,UAAU,EAAE,sBAAsB;EAClCC,gBAAgB,EAAE,4BAA4B;EAC9CC,YAAY,EAAE,wBAAwB;EACtCC,yBAAyB,EAAE,4CAA4C;EACvEC,UAAU,EAAE,sBAAsB;EAClC,GAAGC,qBAAQ,CAACC,MAAM,CAAC;IACjBC,OAAO,EAAE;MACPd,QAAQ,EAAE,wCAAwC;MAClDC,eAAe,EAAE,wCAAwC;MACzDC,MAAM,EAAE,wCAAwC;MAChDC,YAAY,EAAE,wCAAwC;MACtDY,kBAAkB,EAAE,wCAAwC;MAC5DX,QAAQ,EAAE,wCAAwC;MAClDC,qBAAqB,EAAE;IACzB,CAAC;IACDW,GAAG,EAAE;MACHhB,QAAQ,EAAE,wCAAwC;MAClDC,eAAe,EAAE,wCAAwC;MACzDC,MAAM,EAAE,wCAAwC;MAChDC,YAAY,EAAE,wCAAwC;MACtDY,kBAAkB,EAAE,wCAAwC;MAC5DX,QAAQ,EAAE,wCAAwC;MAClDC,qBAAqB,EAAE;IACzB;EACF,CAAC;AACH,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["_reactNative","require","TestIds","exports","APP_OPEN","ADAPTIVE_BANNER","BANNER","INTERSTITIAL","REWARDED","REWARDED_INTERSTITIAL","NATIVE","NATIVE_VIDEO","GAM_APP_OPEN","GAM_BANNER","GAM_INTERSTITIAL","GAM_REWARDED","GAM_REWARDED_INTERSTITIAL","GAM_NATIVE","GAM_NATIVE_VIDEO","Platform","select","android","INTERSTITIAL_VIDEO","ios"],"sourceRoot":"../../src","sources":["TestIds.ts"],"mappings":";;;;;;AAiBA,IAAAA,YAAA,GAAAC,OAAA;AAjBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAIO,MAAMC,OAAO,GAAAC,OAAA,CAAAD,OAAA,GAAG;EACrBE,QAAQ,EAAE,EAAE;EACZC,eAAe,EAAE,EAAE;EACnBC,MAAM,EAAE,EAAE;EACVC,YAAY,EAAE,EAAE;EAChBC,QAAQ,EAAE,EAAE;EACZC,qBAAqB,EAAE,EAAE;EACzBC,MAAM,EAAE,EAAE;EACVC,YAAY,EAAE,EAAE;EAChBC,YAAY,EAAE,+BAA+B;EAC7CC,UAAU,EAAE,wCAAwC;EACpDC,gBAAgB,EAAE,mCAAmC;EACrDC,YAAY,EAAE,+BAA+B;EAC7CC,yBAAyB,EAAE,4CAA4C;EACvEC,UAAU,EAAE,6BAA6B;EACzCC,gBAAgB,EAAE,mCAAmC;EACrD,GAAGC,qBAAQ,CAACC,MAAM,CAAC;IACjBC,OAAO,EAAE;MACPjB,QAAQ,EAAE,wCAAwC;MAClDC,eAAe,EAAE,wCAAwC;MACzDC,MAAM,EAAE,wCAAwC;MAChDC,YAAY,EAAE,wCAAwC;MACtDe,kBAAkB,EAAE,wCAAwC;MAC5Dd,QAAQ,EAAE,wCAAwC;MAClDC,qBAAqB,EAAE,wCAAwC;MAC/DC,MAAM,EAAE,wCAAwC;MAChDC,YAAY,EAAE;IAChB,CAAC;IACDY,GAAG,EAAE;MACHnB,QAAQ,EAAE,wCAAwC;MAClDC,eAAe,EAAE,wCAAwC;MACzDC,MAAM,EAAE,wCAAwC;MAChDC,YAAY,EAAE,wCAAwC;MACtDe,kBAAkB,EAAE,wCAAwC;MAC5Dd,QAAQ,EAAE,wCAAwC;MAClDC,qBAAqB,EAAE,wCAAwC;MAC/DC,MAAM,EAAE,wCAAwC;MAChDC,YAAY,EAAE;IAChB;EACF,CAAC;AACH,CAAC","ignoreList":[]}