react-native-google-mobile-ads 5.1.1 → 6.0.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.
- package/__tests__/interstitial.test.ts +32 -5
- package/android/src/main/java/io/invertase/googlemobileads/ReactNativeGoogleMobileAdsAppOpenModule.java +2 -1
- package/android/src/main/java/io/invertase/googlemobileads/ReactNativeGoogleMobileAdsBannerAdViewManager.java +110 -68
- package/android/src/main/java/io/invertase/googlemobileads/ReactNativeGoogleMobileAdsCommon.java +5 -11
- package/android/src/main/java/io/invertase/googlemobileads/ReactNativeGoogleMobileAdsEvent.java +1 -0
- package/android/src/main/java/io/invertase/googlemobileads/ReactNativeGoogleMobileAdsInterstitialModule.java +38 -20
- package/android/src/main/java/io/invertase/googlemobileads/ReactNativeGoogleMobileAdsModule.java +45 -0
- package/docs/ad-inspector.mdx +39 -0
- package/docs/displaying-ads.mdx +46 -25
- package/docs/migrating-to-v6.mdx +111 -0
- package/docs.json +3 -1
- package/ios/RNGoogleMobileAds/RNGoogleMobileAdsAppOpenModule.m +1 -0
- package/ios/RNGoogleMobileAds/RNGoogleMobileAdsBannerViewManager.m +63 -8
- package/ios/RNGoogleMobileAds/RNGoogleMobileAdsCommon.h +3 -0
- package/ios/RNGoogleMobileAds/RNGoogleMobileAdsCommon.m +8 -7
- package/ios/RNGoogleMobileAds/RNGoogleMobileAdsFullScreenContentDelegate.h +2 -1
- package/ios/RNGoogleMobileAds/RNGoogleMobileAdsFullScreenContentDelegate.m +17 -2
- package/ios/RNGoogleMobileAds/RNGoogleMobileAdsInterstitialModule.m +44 -30
- package/ios/RNGoogleMobileAds/RNGoogleMobileAdsModule.m +19 -0
- package/lib/commonjs/AdEventType.js.map +1 -1
- package/lib/commonjs/GAMAdEventType.js +30 -0
- package/lib/commonjs/GAMAdEventType.js.map +1 -0
- package/lib/commonjs/MobileAds.js +4 -0
- package/lib/commonjs/MobileAds.js.map +1 -1
- package/lib/commonjs/RewardedAdEventType.js.map +1 -1
- package/lib/commonjs/TestIds.js +5 -0
- package/lib/commonjs/TestIds.js.map +1 -1
- package/lib/commonjs/ads/AppOpenAd.js +8 -53
- package/lib/commonjs/ads/AppOpenAd.js.map +1 -1
- package/lib/commonjs/ads/BannerAd.js +7 -110
- package/lib/commonjs/ads/BannerAd.js.map +1 -1
- package/lib/commonjs/ads/BaseAd.js +144 -0
- package/lib/commonjs/ads/BaseAd.js.map +1 -0
- package/lib/commonjs/ads/GAMBannerAd.js +42 -0
- package/lib/commonjs/ads/GAMBannerAd.js.map +1 -0
- package/lib/commonjs/ads/GAMInterstitialAd.js +48 -0
- package/lib/commonjs/ads/GAMInterstitialAd.js.map +1 -0
- package/lib/commonjs/ads/InterstitialAd.js +13 -64
- package/lib/commonjs/ads/InterstitialAd.js.map +1 -1
- package/lib/commonjs/ads/MobileAd.js +119 -12
- package/lib/commonjs/ads/MobileAd.js.map +1 -1
- package/lib/commonjs/ads/RewardedAd.js +23 -65
- package/lib/commonjs/ads/RewardedAd.js.map +1 -1
- package/lib/commonjs/hooks/useAppOpenAd.js.map +1 -1
- package/lib/commonjs/hooks/useFullScreenAd.js +9 -4
- package/lib/commonjs/hooks/useFullScreenAd.js.map +1 -1
- package/lib/commonjs/hooks/useInterstitialAd.js.map +1 -1
- package/lib/commonjs/index.js +62 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/types/AdEventsListener.js +6 -0
- package/lib/commonjs/types/AdEventsListener.js.map +1 -0
- package/lib/commonjs/types/AppEvent.js +2 -0
- package/lib/commonjs/types/AppEvent.js.map +1 -0
- package/lib/commonjs/types/index.js +149 -0
- package/lib/commonjs/types/index.js.map +1 -0
- package/lib/commonjs/validateAdRequestOptions.js +0 -38
- package/lib/commonjs/validateAdRequestOptions.js.map +1 -1
- package/lib/commonjs/version.js +2 -2
- package/lib/commonjs/version.js.map +1 -1
- package/lib/module/AdEventType.js.map +1 -1
- package/lib/module/GAMAdEventType.js +22 -0
- package/lib/module/GAMAdEventType.js.map +1 -0
- package/lib/module/MobileAds.js +4 -0
- package/lib/module/MobileAds.js.map +1 -1
- package/lib/module/RewardedAdEventType.js.map +1 -1
- package/lib/module/TestIds.js +5 -0
- package/lib/module/TestIds.js.map +1 -1
- package/lib/module/ads/AppOpenAd.js +10 -37
- package/lib/module/ads/AppOpenAd.js.map +1 -1
- package/lib/module/ads/BannerAd.js +7 -85
- package/lib/module/ads/BannerAd.js.map +1 -1
- package/lib/module/ads/BaseAd.js +124 -0
- package/lib/module/ads/BaseAd.js.map +1 -0
- package/lib/module/ads/GAMBannerAd.js +42 -0
- package/lib/module/ads/GAMBannerAd.js.map +1 -0
- package/lib/module/ads/GAMInterstitialAd.js +38 -0
- package/lib/module/ads/GAMInterstitialAd.js.map +1 -0
- package/lib/module/ads/InterstitialAd.js +15 -48
- package/lib/module/ads/InterstitialAd.js.map +1 -1
- package/lib/module/ads/MobileAd.js +116 -12
- package/lib/module/ads/MobileAd.js.map +1 -1
- package/lib/module/ads/RewardedAd.js +24 -49
- package/lib/module/ads/RewardedAd.js.map +1 -1
- package/lib/module/hooks/useAppOpenAd.js.map +1 -1
- package/lib/module/hooks/useFullScreenAd.js +9 -4
- package/lib/module/hooks/useFullScreenAd.js.map +1 -1
- package/lib/module/hooks/useInterstitialAd.js.map +1 -1
- package/lib/module/index.js +4 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/types/AdEventsListener.js +2 -0
- package/lib/module/types/AdEventsListener.js.map +1 -0
- package/lib/module/types/AppEvent.js +2 -0
- package/lib/module/types/AppEvent.js.map +1 -0
- package/lib/module/types/index.js +28 -0
- package/lib/module/types/index.js.map +1 -0
- package/lib/module/validateAdRequestOptions.js +1 -39
- package/lib/module/validateAdRequestOptions.js.map +1 -1
- package/lib/module/version.js +2 -2
- package/lib/module/version.js.map +1 -1
- package/lib/typescript/AdEventType.d.ts +4 -8
- package/lib/typescript/GAMAdEventType.d.ts +20 -0
- package/lib/typescript/MobileAds.d.ts +2 -1
- package/lib/typescript/RewardedAdEventType.d.ts +7 -11
- package/lib/typescript/TestIds.d.ts +5 -0
- package/lib/typescript/ads/AppOpenAd.d.ts +6 -6
- package/lib/typescript/ads/BannerAd.d.ts +1 -1
- package/lib/typescript/ads/BaseAd.d.ts +35 -0
- package/lib/typescript/ads/GAMBannerAd.d.ts +7 -0
- package/lib/typescript/ads/GAMInterstitialAd.d.ts +33 -0
- package/lib/typescript/ads/InterstitialAd.d.ts +10 -16
- package/lib/typescript/ads/MobileAd.d.ts +34 -16
- package/lib/typescript/ads/RewardedAd.d.ts +17 -19
- package/lib/typescript/hooks/useAppOpenAd.d.ts +1 -1
- package/lib/typescript/hooks/useInterstitialAd.d.ts +1 -1
- package/lib/typescript/index.d.ts +5 -1
- package/lib/typescript/types/AdEventListener.d.ts +5 -9
- package/lib/typescript/types/AdEventsListener.d.ts +8 -0
- package/lib/typescript/types/AppEvent.d.ts +13 -0
- package/lib/typescript/types/BannerAdProps.d.ts +81 -4
- package/lib/typescript/types/GoogleMobileAdsNativeModule.d.ts +3 -2
- package/lib/typescript/types/MobileAd.interface.d.ts +37 -12
- package/lib/typescript/types/MobileAdsModule.interface.d.ts +9 -0
- package/lib/typescript/types/RequestOptions.d.ts +0 -22
- package/lib/typescript/types/index.d.ts +11 -0
- package/lib/typescript/version.d.ts +1 -1
- package/package.json +50 -49
- package/src/AdEventType.ts +4 -8
- package/src/GAMAdEventType.ts +37 -0
- package/src/MobileAds.ts +4 -0
- package/src/RewardedAdEventType.ts +7 -11
- package/src/TestIds.ts +5 -0
- package/src/ads/AppOpenAd.ts +11 -41
- package/src/ads/BannerAd.tsx +4 -106
- package/src/ads/BaseAd.tsx +156 -0
- package/src/ads/GAMBannerAd.tsx +37 -0
- package/src/ads/GAMInterstitialAd.ts +45 -0
- package/src/ads/InterstitialAd.ts +15 -56
- package/src/ads/MobileAd.ts +142 -29
- package/src/ads/RewardedAd.ts +29 -55
- package/src/hooks/useAppOpenAd.ts +1 -1
- package/src/hooks/useFullScreenAd.ts +5 -4
- package/src/hooks/useInterstitialAd.ts +1 -1
- package/src/index.ts +4 -0
- package/src/types/AdEventListener.ts +31 -13
- package/src/types/AdEventsListener.ts +24 -0
- package/src/types/AppEvent.ts +14 -0
- package/src/types/BannerAdProps.ts +81 -4
- package/src/types/GoogleMobileAdsNativeModule.ts +3 -2
- package/src/types/MobileAd.interface.ts +56 -12
- package/src/types/MobileAdsModule.interface.ts +10 -0
- package/src/types/RequestOptions.ts +0 -24
- package/src/types/index.ts +28 -0
- package/src/validateAdRequestOptions.ts +0 -45
- package/src/version.ts +2 -2
package/src/ads/BannerAd.tsx
CHANGED
|
@@ -15,112 +15,10 @@
|
|
|
15
15
|
*
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
-
import React
|
|
19
|
-
import { HostComponent, requireNativeComponent } from 'react-native';
|
|
20
|
-
import { isFunction } from '../common';
|
|
21
|
-
import { NativeError } from '../internal/NativeError';
|
|
22
|
-
import { BannerAdSize } from '../BannerAdSize';
|
|
23
|
-
import { validateAdRequestOptions } from '../validateAdRequestOptions';
|
|
18
|
+
import React from 'react';
|
|
24
19
|
import { BannerAdProps } from '../types/BannerAdProps';
|
|
25
|
-
import {
|
|
20
|
+
import { BaseAd } from './BaseAd';
|
|
26
21
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
type: 'onAdLoaded' | 'onSizeChange';
|
|
30
|
-
width: number;
|
|
31
|
-
height: number;
|
|
32
|
-
}
|
|
33
|
-
| { type: 'onAdOpened' | 'onAdClosed' }
|
|
34
|
-
| {
|
|
35
|
-
type: 'onAdFailedToLoad';
|
|
36
|
-
code: string;
|
|
37
|
-
message: string;
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
const initialState = [0, 0];
|
|
41
|
-
const sizeRegex = /([0-9]+)x([0-9]+)/;
|
|
42
|
-
|
|
43
|
-
export function BannerAd({ unitId, size, requestOptions, ...props }: BannerAdProps) {
|
|
44
|
-
const [dimensions, setDimensions] = useState(initialState);
|
|
45
|
-
|
|
46
|
-
useEffect(() => {
|
|
47
|
-
if (!unitId) {
|
|
48
|
-
throw new Error("BannerAd: 'unitId' expected a valid string unit ID.");
|
|
49
|
-
}
|
|
50
|
-
}, [unitId]);
|
|
51
|
-
|
|
52
|
-
useEffect(() => {
|
|
53
|
-
if (!(size in BannerAdSize) && !sizeRegex.test(size)) {
|
|
54
|
-
throw new Error("BannerAd: 'size' expected a valid BannerAdSize or custom size string.");
|
|
55
|
-
}
|
|
56
|
-
}, [size]);
|
|
57
|
-
|
|
58
|
-
useEffect(() => {
|
|
59
|
-
if (!(size in BannerAdSize) && !sizeRegex.test(size)) {
|
|
60
|
-
throw new Error("BannerAd: 'size' expected a valid BannerAdSize or custom size string.");
|
|
61
|
-
}
|
|
62
|
-
}, [size]);
|
|
63
|
-
|
|
64
|
-
const parsedRequestOptions = JSON.stringify(requestOptions);
|
|
65
|
-
|
|
66
|
-
useEffect(() => {
|
|
67
|
-
if (requestOptions) {
|
|
68
|
-
try {
|
|
69
|
-
validateAdRequestOptions(requestOptions);
|
|
70
|
-
} catch (e) {
|
|
71
|
-
if (e instanceof Error) {
|
|
72
|
-
throw new Error(`BannerAd: ${e.message}`);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
}, [parsedRequestOptions]);
|
|
77
|
-
|
|
78
|
-
function onNativeEvent({ nativeEvent }: { nativeEvent: NativeEvent }) {
|
|
79
|
-
const { type } = nativeEvent;
|
|
80
|
-
|
|
81
|
-
if (type !== 'onSizeChange' && isFunction(props[type])) {
|
|
82
|
-
let eventHandler;
|
|
83
|
-
if (type === 'onAdFailedToLoad') {
|
|
84
|
-
const eventPayload = NativeError.fromEvent(nativeEvent, 'googleMobileAds');
|
|
85
|
-
if ((eventHandler = props[type])) eventHandler(eventPayload);
|
|
86
|
-
} else if ((eventHandler = props[type])) eventHandler();
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
if ((type === 'onAdLoaded' || type === 'onSizeChange') && size !== 'FLUID') {
|
|
90
|
-
const { width, height } = nativeEvent;
|
|
91
|
-
if (width && height) setDimensions([width, height]);
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
let style;
|
|
96
|
-
if (size === 'FLUID') {
|
|
97
|
-
// @ts-ignore: Property 'style' does not exist on type error
|
|
98
|
-
style = props.style;
|
|
99
|
-
} else {
|
|
100
|
-
style = {
|
|
101
|
-
width: dimensions[0],
|
|
102
|
-
height: dimensions[1],
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
return (
|
|
107
|
-
<GoogleMobileAdsBannerView
|
|
108
|
-
size={size}
|
|
109
|
-
style={style}
|
|
110
|
-
unitId={unitId}
|
|
111
|
-
request={validateAdRequestOptions(requestOptions)}
|
|
112
|
-
onNativeEvent={onNativeEvent}
|
|
113
|
-
/>
|
|
114
|
-
);
|
|
22
|
+
export function BannerAd({ size, ...props }: BannerAdProps) {
|
|
23
|
+
return <BaseAd sizes={[size]} {...props} />;
|
|
115
24
|
}
|
|
116
|
-
|
|
117
|
-
const GoogleMobileAdsBannerView: HostComponent<{
|
|
118
|
-
size: BannerAdProps['size'];
|
|
119
|
-
style: {
|
|
120
|
-
width: number;
|
|
121
|
-
height: number;
|
|
122
|
-
};
|
|
123
|
-
unitId: string;
|
|
124
|
-
request: RequestOptions;
|
|
125
|
-
onNativeEvent: (event: { nativeEvent: NativeEvent }) => void;
|
|
126
|
-
}> = requireNativeComponent('RNGoogleMobileAdsBannerView');
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/* eslint-disable react/prop-types */
|
|
2
|
+
/*
|
|
3
|
+
* Copyright (c) 2016-present Invertase Limited & Contributors
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this library except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import React, { useState, useEffect } from 'react';
|
|
20
|
+
import { NativeMethods, requireNativeComponent } from 'react-native';
|
|
21
|
+
import { isFunction } from '../common';
|
|
22
|
+
import { NativeError } from '../internal/NativeError';
|
|
23
|
+
import { BannerAdSize } from '../BannerAdSize';
|
|
24
|
+
import { validateAdRequestOptions } from '../validateAdRequestOptions';
|
|
25
|
+
import { GAMBannerAdProps } from '../types/BannerAdProps';
|
|
26
|
+
import { RequestOptions } from '../types/RequestOptions';
|
|
27
|
+
|
|
28
|
+
type NativeEvent =
|
|
29
|
+
| {
|
|
30
|
+
type: 'onAdLoaded' | 'onSizeChange';
|
|
31
|
+
width: number;
|
|
32
|
+
height: number;
|
|
33
|
+
}
|
|
34
|
+
| { type: 'onAdOpened' | 'onAdClosed' }
|
|
35
|
+
| {
|
|
36
|
+
type: 'onAdFailedToLoad';
|
|
37
|
+
code: string;
|
|
38
|
+
message: string;
|
|
39
|
+
}
|
|
40
|
+
| {
|
|
41
|
+
type: 'onAppEvent';
|
|
42
|
+
name: string;
|
|
43
|
+
data?: string;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const sizeRegex = /([0-9]+)x([0-9]+)/;
|
|
47
|
+
|
|
48
|
+
export const BaseAd = React.forwardRef<GoogleMobileAdsBannerView, GAMBannerAdProps>(
|
|
49
|
+
({ unitId, sizes, requestOptions, manualImpressionsEnabled, ...props }, ref) => {
|
|
50
|
+
const [dimensions, setDimensions] = useState<(number | string)[]>([0, 0]);
|
|
51
|
+
|
|
52
|
+
useEffect(() => {
|
|
53
|
+
if (!unitId) {
|
|
54
|
+
throw new Error("BannerAd: 'unitId' expected a valid string unit ID.");
|
|
55
|
+
}
|
|
56
|
+
}, [unitId]);
|
|
57
|
+
|
|
58
|
+
useEffect(() => {
|
|
59
|
+
if (
|
|
60
|
+
sizes.length === 0 ||
|
|
61
|
+
!sizes.every(size => size in BannerAdSize || sizeRegex.test(size))
|
|
62
|
+
) {
|
|
63
|
+
throw new Error("BannerAd: 'size(s)' expected a valid BannerAdSize or custom size string.");
|
|
64
|
+
}
|
|
65
|
+
}, [sizes]);
|
|
66
|
+
|
|
67
|
+
const parsedRequestOptions = JSON.stringify(requestOptions);
|
|
68
|
+
|
|
69
|
+
useEffect(() => {
|
|
70
|
+
if (requestOptions) {
|
|
71
|
+
try {
|
|
72
|
+
validateAdRequestOptions(requestOptions);
|
|
73
|
+
} catch (e) {
|
|
74
|
+
if (e instanceof Error) {
|
|
75
|
+
throw new Error(`BannerAd: ${e.message}`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}, [parsedRequestOptions]);
|
|
80
|
+
|
|
81
|
+
function onNativeEvent({ nativeEvent }: { nativeEvent: NativeEvent }) {
|
|
82
|
+
const { type } = nativeEvent;
|
|
83
|
+
|
|
84
|
+
if (type !== 'onSizeChange' && isFunction(props[type])) {
|
|
85
|
+
let eventHandler, eventPayload;
|
|
86
|
+
switch (type) {
|
|
87
|
+
case 'onAdLoaded':
|
|
88
|
+
eventPayload = {
|
|
89
|
+
width: nativeEvent.width,
|
|
90
|
+
height: nativeEvent.height,
|
|
91
|
+
};
|
|
92
|
+
if ((eventHandler = props[type])) eventHandler(eventPayload);
|
|
93
|
+
break;
|
|
94
|
+
case 'onAdFailedToLoad':
|
|
95
|
+
eventPayload = NativeError.fromEvent(nativeEvent, 'googleMobileAds');
|
|
96
|
+
if ((eventHandler = props[type])) eventHandler(eventPayload);
|
|
97
|
+
break;
|
|
98
|
+
case 'onAppEvent':
|
|
99
|
+
eventPayload = {
|
|
100
|
+
name: nativeEvent.name,
|
|
101
|
+
data: nativeEvent.data,
|
|
102
|
+
};
|
|
103
|
+
if ((eventHandler = props[type])) eventHandler(eventPayload);
|
|
104
|
+
break;
|
|
105
|
+
default:
|
|
106
|
+
if ((eventHandler = props[type])) eventHandler();
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (type === 'onAdLoaded' || type === 'onSizeChange') {
|
|
111
|
+
const { width, height } = nativeEvent;
|
|
112
|
+
if (width && height) setDimensions([width, height]);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const style = sizes.includes(BannerAdSize.FLUID)
|
|
117
|
+
? {
|
|
118
|
+
width: '100%',
|
|
119
|
+
height: dimensions[1],
|
|
120
|
+
}
|
|
121
|
+
: {
|
|
122
|
+
width: dimensions[0],
|
|
123
|
+
height: dimensions[1],
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
return (
|
|
127
|
+
<GoogleMobileAdsBannerView
|
|
128
|
+
ref={ref}
|
|
129
|
+
sizes={sizes}
|
|
130
|
+
style={style}
|
|
131
|
+
unitId={unitId}
|
|
132
|
+
request={validateAdRequestOptions(requestOptions)}
|
|
133
|
+
manualImpressionsEnabled={!!manualImpressionsEnabled}
|
|
134
|
+
onNativeEvent={onNativeEvent}
|
|
135
|
+
/>
|
|
136
|
+
);
|
|
137
|
+
},
|
|
138
|
+
);
|
|
139
|
+
BaseAd.displayName = 'BaseAd';
|
|
140
|
+
|
|
141
|
+
interface NativeBannerProps {
|
|
142
|
+
sizes: GAMBannerAdProps['sizes'];
|
|
143
|
+
style: {
|
|
144
|
+
width?: number | string;
|
|
145
|
+
height?: number | string;
|
|
146
|
+
};
|
|
147
|
+
unitId: string;
|
|
148
|
+
request: RequestOptions;
|
|
149
|
+
manualImpressionsEnabled: boolean;
|
|
150
|
+
onNativeEvent: (event: { nativeEvent: NativeEvent }) => void;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const GoogleMobileAdsBannerView = requireNativeComponent<NativeBannerProps>(
|
|
154
|
+
'RNGoogleMobileAdsBannerView',
|
|
155
|
+
);
|
|
156
|
+
export type GoogleMobileAdsBannerView = React.Component<NativeBannerProps> & NativeMethods;
|
|
@@ -0,0 +1,37 @@
|
|
|
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 React, { createRef } from 'react';
|
|
19
|
+
import { findNodeHandle, UIManager } from 'react-native';
|
|
20
|
+
import { GAMBannerAdProps } from '../types/BannerAdProps';
|
|
21
|
+
import { BaseAd, GoogleMobileAdsBannerView } from './BaseAd';
|
|
22
|
+
|
|
23
|
+
export class GAMBannerAd extends React.Component<GAMBannerAdProps> {
|
|
24
|
+
private ref = createRef<GoogleMobileAdsBannerView>();
|
|
25
|
+
|
|
26
|
+
recordManualImpression() {
|
|
27
|
+
UIManager.dispatchViewManagerCommand(
|
|
28
|
+
findNodeHandle(this.ref.current),
|
|
29
|
+
'recordManualImpression',
|
|
30
|
+
undefined,
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
render() {
|
|
35
|
+
return <BaseAd ref={this.ref} {...this.props} />;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { AdEventType } from '../AdEventType';
|
|
2
|
+
import { GAMAdEventType } from '../GAMAdEventType';
|
|
3
|
+
import { AdEventListener } from '../types/AdEventListener';
|
|
4
|
+
import { AdEventsListener } from '../types/AdEventsListener';
|
|
5
|
+
import { RequestOptions } from '../types/RequestOptions';
|
|
6
|
+
import { InterstitialAd } from './InterstitialAd';
|
|
7
|
+
|
|
8
|
+
export class GAMInterstitialAd extends InterstitialAd {
|
|
9
|
+
/**
|
|
10
|
+
* Creates a new GAMInterstitialAd instance.
|
|
11
|
+
*
|
|
12
|
+
* #### Example
|
|
13
|
+
*
|
|
14
|
+
* ```js
|
|
15
|
+
* import { GAMInterstitialAd, AdEventType, TestIds } from 'react-native-google-mobile-ads';
|
|
16
|
+
*
|
|
17
|
+
* const interstitialAd = await GAMInterstitialAd.createForAdRequest(TestIds.GAM_INTERSTITIAL, {
|
|
18
|
+
* requestAgent: 'CoolAds',
|
|
19
|
+
* });
|
|
20
|
+
*
|
|
21
|
+
* interstitialAd.addAdEventListener(AdEventType.Loaded, () => {
|
|
22
|
+
* interstitialAd.show();
|
|
23
|
+
* });
|
|
24
|
+
*
|
|
25
|
+
* interstitialAd.load();
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* @param adUnitId The Ad Unit ID for the Interstitial. You can find this on your Google Mobile Ads dashboard.
|
|
29
|
+
* @param requestOptions Optional RequestOptions used to load the ad.
|
|
30
|
+
*/
|
|
31
|
+
static createForAdRequest(adUnitId: string, requestOptions?: RequestOptions) {
|
|
32
|
+
return super.createForAdRequest(adUnitId, requestOptions) as GAMInterstitialAd;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
addAdEventsListener<T extends AdEventType | GAMAdEventType>(listener: AdEventsListener<T>) {
|
|
36
|
+
return this._addAdEventsListener(listener);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
addAdEventListener<T extends AdEventType | GAMAdEventType>(
|
|
40
|
+
type: T,
|
|
41
|
+
listener: AdEventListener<T>,
|
|
42
|
+
) {
|
|
43
|
+
return this._addAdEventListener(type, listener);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -15,17 +15,14 @@
|
|
|
15
15
|
*
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
-
import {
|
|
18
|
+
import { isString } from '../common';
|
|
19
19
|
import { MobileAds } from '../MobileAds';
|
|
20
20
|
import { validateAdRequestOptions } from '../validateAdRequestOptions';
|
|
21
|
-
import { validateAdShowOptions } from '../validateAdShowOptions';
|
|
22
21
|
import { MobileAd } from './MobileAd';
|
|
22
|
+
import { AdEventType } from '../AdEventType';
|
|
23
23
|
import { AdEventListener } from '../types/AdEventListener';
|
|
24
|
-
import {
|
|
24
|
+
import { AdEventsListener } from '../types/AdEventsListener';
|
|
25
25
|
import { RequestOptions } from '../types/RequestOptions';
|
|
26
|
-
import { MobileAdInterface } from '../types/MobileAd.interface';
|
|
27
|
-
|
|
28
|
-
let _interstitialRequest = 0;
|
|
29
26
|
|
|
30
27
|
/**
|
|
31
28
|
* A class for interacting and showing Interstitial Ads.
|
|
@@ -56,10 +53,8 @@ let _interstitialRequest = 0;
|
|
|
56
53
|
* ```js
|
|
57
54
|
* import { AdEventType } from 'react-native-google-mobile-ads';
|
|
58
55
|
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
* interstitial.show();
|
|
62
|
-
* }
|
|
56
|
+
* interstitialAd.addAdEventListener(AdEventType.Loaded, () => {
|
|
57
|
+
* interstitialAd.show();
|
|
63
58
|
* });
|
|
64
59
|
*
|
|
65
60
|
* interstitial.load();
|
|
@@ -68,7 +63,8 @@ let _interstitialRequest = 0;
|
|
|
68
63
|
* The advert will be presented to the user, and several more events can be triggered such as the user clicking the
|
|
69
64
|
* advert or closing it.
|
|
70
65
|
*/
|
|
71
|
-
export class InterstitialAd extends MobileAd
|
|
66
|
+
export class InterstitialAd extends MobileAd {
|
|
67
|
+
protected static _interstitialRequest = 0;
|
|
72
68
|
/**
|
|
73
69
|
* Creates a new InterstitialAd instance.
|
|
74
70
|
*
|
|
@@ -81,12 +77,8 @@ export class InterstitialAd extends MobileAd implements MobileAdInterface {
|
|
|
81
77
|
* requestAgent: 'CoolAds',
|
|
82
78
|
* });
|
|
83
79
|
*
|
|
84
|
-
* interstitialAd.
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
* if (type === AdEventType.LOADED) {
|
|
88
|
-
* interstitialAd.show();
|
|
89
|
-
* }
|
|
80
|
+
* interstitialAd.addAdEventListener(AdEventType.Loaded, () => {
|
|
81
|
+
* interstitialAd.show();
|
|
90
82
|
* });
|
|
91
83
|
*
|
|
92
84
|
* interstitialAd.load();
|
|
@@ -95,7 +87,7 @@ export class InterstitialAd extends MobileAd implements MobileAdInterface {
|
|
|
95
87
|
* @param adUnitId The Ad Unit ID for the Interstitial. You can find this on your Google Mobile Ads dashboard.
|
|
96
88
|
* @param requestOptions Optional RequestOptions used to load the ad.
|
|
97
89
|
*/
|
|
98
|
-
static createForAdRequest(adUnitId: string, requestOptions?: RequestOptions)
|
|
90
|
+
static createForAdRequest(adUnitId: string, requestOptions?: RequestOptions) {
|
|
99
91
|
if (!isString(adUnitId)) {
|
|
100
92
|
throw new Error("InterstitialAd.createForAdRequest(*) 'adUnitId' expected an string value.");
|
|
101
93
|
}
|
|
@@ -109,48 +101,15 @@ export class InterstitialAd extends MobileAd implements MobileAdInterface {
|
|
|
109
101
|
}
|
|
110
102
|
}
|
|
111
103
|
|
|
112
|
-
const requestId = _interstitialRequest++;
|
|
104
|
+
const requestId = InterstitialAd._interstitialRequest++;
|
|
113
105
|
return new InterstitialAd('interstitial', MobileAds(), requestId, adUnitId, options);
|
|
114
106
|
}
|
|
115
107
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
if (this._loaded || this._isLoadCalled) {
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
this._isLoadCalled = true;
|
|
123
|
-
this._googleMobileAds.native.interstitialLoad(
|
|
124
|
-
this._requestId,
|
|
125
|
-
this._adUnitId,
|
|
126
|
-
this._requestOptions,
|
|
127
|
-
);
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
onAdEvent(handler: AdEventListener) {
|
|
131
|
-
if (!isFunction(handler)) {
|
|
132
|
-
throw new Error("InterstitialAd.onAdEvent(*) 'handler' expected a function.");
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
return this._setAdEventHandler(handler);
|
|
108
|
+
addAdEventsListener<T extends AdEventType>(listener: AdEventsListener<T>) {
|
|
109
|
+
return this._addAdEventsListener(listener);
|
|
136
110
|
}
|
|
137
111
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
throw new Error(
|
|
141
|
-
'InterstitialAd.show() The requested InterstitialAd has not loaded and could not be shown.',
|
|
142
|
-
);
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
let options;
|
|
146
|
-
try {
|
|
147
|
-
options = validateAdShowOptions(showOptions);
|
|
148
|
-
} catch (e) {
|
|
149
|
-
if (e instanceof Error) {
|
|
150
|
-
throw new Error(`InterstitialAd.show(*) ${e.message}.`);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
return this._googleMobileAds.native.interstitialShow(this._requestId, options);
|
|
112
|
+
addAdEventListener<T extends AdEventType>(type: T, listener: AdEventListener<T>) {
|
|
113
|
+
return this._addAdEventListener(type, listener);
|
|
155
114
|
}
|
|
156
115
|
}
|
package/src/ads/MobileAd.ts
CHANGED
|
@@ -16,26 +16,38 @@
|
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
18
|
import { EmitterSubscription } from 'react-native';
|
|
19
|
+
import { isFunction, isOneOf } from '../common';
|
|
19
20
|
import { NativeError } from '../internal/NativeError';
|
|
20
|
-
import { RewardedAdEventType } from '../RewardedAdEventType';
|
|
21
21
|
import { AdEventType } from '../AdEventType';
|
|
22
|
-
import {
|
|
22
|
+
import { RewardedAdEventType } from '../RewardedAdEventType';
|
|
23
|
+
import { AdEventListener, AdEventPayload } from '../types/AdEventListener';
|
|
24
|
+
import { AdEventsListener } from '../types/AdEventsListener';
|
|
25
|
+
import { AdShowOptions } from '../types/AdShowOptions';
|
|
23
26
|
import { RequestOptions } from '../types/RequestOptions';
|
|
27
|
+
import { MobileAdInterface } from '../types/MobileAd.interface';
|
|
24
28
|
import { MobileAdsModuleInterface } from '../types/MobileAdsModule.interface';
|
|
25
29
|
import { RewardedAdReward } from '../types/RewardedAdReward';
|
|
30
|
+
import { GAMAdEventType } from '../GAMAdEventType';
|
|
31
|
+
import { AppEvent } from '../types/AppEvent';
|
|
32
|
+
import { validateAdShowOptions } from '../validateAdShowOptions';
|
|
33
|
+
|
|
34
|
+
type EventType = AdEventType | RewardedAdEventType | GAMAdEventType;
|
|
35
|
+
|
|
36
|
+
export abstract class MobileAd implements MobileAdInterface {
|
|
37
|
+
protected _type: 'app_open' | 'interstitial' | 'rewarded';
|
|
38
|
+
protected _googleMobileAds: MobileAdsModuleInterface;
|
|
39
|
+
protected _requestId: number;
|
|
40
|
+
protected _adUnitId: string;
|
|
41
|
+
protected _requestOptions: RequestOptions;
|
|
42
|
+
protected _loaded: boolean;
|
|
43
|
+
protected _isLoadCalled: boolean;
|
|
44
|
+
protected _adEventsListeners: Map<number, AdEventsListener<EventType>>;
|
|
45
|
+
protected _adEventListenersMap: Map<EventType, Map<number, AdEventListener<EventType>>>;
|
|
46
|
+
protected _adEventsListenerId: number;
|
|
47
|
+
protected _adEventListenerId: number;
|
|
48
|
+
protected _nativeListener: EmitterSubscription;
|
|
26
49
|
|
|
27
|
-
|
|
28
|
-
_type: 'app_open' | 'interstitial' | 'rewarded';
|
|
29
|
-
_googleMobileAds: MobileAdsModuleInterface;
|
|
30
|
-
_requestId: number;
|
|
31
|
-
_adUnitId: string;
|
|
32
|
-
_requestOptions: RequestOptions;
|
|
33
|
-
_loaded: boolean;
|
|
34
|
-
_isLoadCalled: boolean;
|
|
35
|
-
_onAdEventHandler: AdEventListener | null;
|
|
36
|
-
_nativeListener: EmitterSubscription;
|
|
37
|
-
|
|
38
|
-
constructor(
|
|
50
|
+
protected constructor(
|
|
39
51
|
type: 'app_open' | 'interstitial' | 'rewarded',
|
|
40
52
|
googleMobileAds: MobileAdsModuleInterface,
|
|
41
53
|
requestId: number,
|
|
@@ -50,7 +62,18 @@ export class MobileAd {
|
|
|
50
62
|
|
|
51
63
|
this._loaded = false;
|
|
52
64
|
this._isLoadCalled = false;
|
|
53
|
-
this.
|
|
65
|
+
this._adEventsListeners = new Map();
|
|
66
|
+
this._adEventListenersMap = new Map();
|
|
67
|
+
Object.values({
|
|
68
|
+
...AdEventType,
|
|
69
|
+
...RewardedAdEventType,
|
|
70
|
+
...GAMAdEventType,
|
|
71
|
+
_: AdEventType.LOADED, // since AdEventType.LOADED is overwritten by RewardedAdEventType.LOADED
|
|
72
|
+
}).forEach(type => {
|
|
73
|
+
this._adEventListenersMap.set(type as EventType, new Map());
|
|
74
|
+
});
|
|
75
|
+
this._adEventListenerId = 0;
|
|
76
|
+
this._adEventsListenerId = 0;
|
|
54
77
|
|
|
55
78
|
this._nativeListener = googleMobileAds.emitter.addListener(
|
|
56
79
|
`google_mobile_ads_${type}_event:${adUnitId}:${requestId}`,
|
|
@@ -58,11 +81,11 @@ export class MobileAd {
|
|
|
58
81
|
);
|
|
59
82
|
}
|
|
60
83
|
|
|
61
|
-
_handleAdEvent(event: {
|
|
84
|
+
protected _handleAdEvent(event: {
|
|
62
85
|
body: {
|
|
63
|
-
type:
|
|
86
|
+
type: EventType;
|
|
64
87
|
error?: { code: string; message: string };
|
|
65
|
-
data?: RewardedAdReward;
|
|
88
|
+
data?: RewardedAdReward | AppEvent;
|
|
66
89
|
};
|
|
67
90
|
}) {
|
|
68
91
|
const { type, error, data } = event.body;
|
|
@@ -76,26 +99,116 @@ export class MobileAd {
|
|
|
76
99
|
this._isLoadCalled = false;
|
|
77
100
|
}
|
|
78
101
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
102
|
+
let payload: AdEventPayload<EventType> = data;
|
|
103
|
+
if (error) {
|
|
104
|
+
payload = NativeError.fromEvent(error, 'googleMobileAds');
|
|
105
|
+
}
|
|
106
|
+
this._adEventsListeners.forEach(listener => {
|
|
107
|
+
listener({
|
|
108
|
+
type,
|
|
109
|
+
payload,
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
this._getAdEventListeners(type).forEach(listener => {
|
|
113
|
+
listener(payload);
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
protected _addAdEventsListener<T extends EventType>(listener: AdEventsListener<T>) {
|
|
118
|
+
if (!isFunction(listener)) {
|
|
119
|
+
throw new Error(`${this._className}.addAdEventsListener(*) 'listener' expected a function.`);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const id = this._adEventsListenerId++;
|
|
123
|
+
this._adEventsListeners.set(id, listener as AdEventsListener<EventType>);
|
|
124
|
+
return () => {
|
|
125
|
+
this._adEventsListeners.delete(id);
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
protected _addAdEventListener<T extends EventType>(type: T, listener: AdEventListener<T>) {
|
|
130
|
+
if (
|
|
131
|
+
!(
|
|
132
|
+
isOneOf(type, Object.values(AdEventType)) ||
|
|
133
|
+
(isOneOf(type, Object.values(RewardedAdEventType)) && this._type === 'rewarded')
|
|
134
|
+
)
|
|
135
|
+
) {
|
|
136
|
+
throw new Error(
|
|
137
|
+
`${this._className}.addAdEventListener(*) 'type' expected a valid event type value.`,
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
if (!isFunction(listener)) {
|
|
141
|
+
throw new Error(
|
|
142
|
+
`${this._className}.addAdEventListener(_, *) 'listener' expected a function.`,
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const id = this._adEventListenerId++;
|
|
147
|
+
this._getAdEventListeners(type).set(id, listener);
|
|
148
|
+
return () => {
|
|
149
|
+
this._getAdEventListeners(type).delete(id);
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
protected _getAdEventListeners<T extends EventType>(type: T) {
|
|
154
|
+
return this._adEventListenersMap.get(type) as Map<number, AdEventListener<T>>;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
protected get _className() {
|
|
158
|
+
return this.constructor.name;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
public load() {
|
|
162
|
+
// Prevent multiple load calls
|
|
163
|
+
if (this._loaded || this._isLoadCalled) {
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
84
166
|
|
|
85
|
-
|
|
167
|
+
this._isLoadCalled = true;
|
|
168
|
+
const type = this._type === 'app_open' ? 'appOpen' : this._type;
|
|
169
|
+
const load = this._googleMobileAds.native[`${type}Load`];
|
|
170
|
+
load(this._requestId, this._adUnitId, this._requestOptions);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
public show(showOptions?: AdShowOptions) {
|
|
174
|
+
if (!this._loaded) {
|
|
175
|
+
throw new Error(
|
|
176
|
+
`${this._className}.show() The requested ${this._className} has not loaded and could not be shown.`,
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
let options;
|
|
181
|
+
try {
|
|
182
|
+
options = validateAdShowOptions(showOptions);
|
|
183
|
+
} catch (e) {
|
|
184
|
+
if (e instanceof Error) {
|
|
185
|
+
throw new Error(`${this._className}.show(*) ${e.message}.`);
|
|
186
|
+
} else {
|
|
187
|
+
throw e;
|
|
188
|
+
}
|
|
86
189
|
}
|
|
190
|
+
|
|
191
|
+
const type = this._type === 'app_open' ? 'appOpen' : this._type;
|
|
192
|
+
const show = this._googleMobileAds.native[`${type}Show`];
|
|
193
|
+
return show(this._requestId, this._adUnitId, options);
|
|
87
194
|
}
|
|
88
195
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
196
|
+
public abstract addAdEventsListener<T extends never>(listener: AdEventsListener<T>): () => void;
|
|
197
|
+
|
|
198
|
+
public abstract addAdEventListener<T extends never>(type: T, listener: AdEventListener<T>): void;
|
|
199
|
+
|
|
200
|
+
public removeAllListeners() {
|
|
201
|
+
this._adEventsListeners.clear();
|
|
202
|
+
this._adEventListenersMap.forEach((_, type, map) => {
|
|
203
|
+
map.set(type, new Map());
|
|
204
|
+
});
|
|
92
205
|
}
|
|
93
206
|
|
|
94
|
-
get adUnitId() {
|
|
207
|
+
public get adUnitId() {
|
|
95
208
|
return this._adUnitId;
|
|
96
209
|
}
|
|
97
210
|
|
|
98
|
-
get loaded() {
|
|
211
|
+
public get loaded() {
|
|
99
212
|
return this._loaded;
|
|
100
213
|
}
|
|
101
214
|
}
|