adwhale-sdk-react-native 2.7.203 → 2.7.300

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 (109) hide show
  1. package/AdwhaleSdkReactNative.podspec +22 -0
  2. package/README.md +105 -39
  3. package/android/build.gradle +15 -15
  4. package/android/proguard-rules.pro +52 -107
  5. package/android/src/main/java/com/adwhalesdkreactnative/AdWhaleCustomNativeBinderFactory.java +18 -0
  6. package/android/src/main/java/com/adwhalesdkreactnative/AdwhaleSdkReactNativePackage.java +51 -6
  7. package/android/src/main/java/com/adwhalesdkreactnative/BinderFactory.java +9 -0
  8. package/android/src/main/java/com/adwhalesdkreactnative/RNAdWhaleMediationAdSettingModule.java +149 -42
  9. package/android/src/main/java/com/adwhalesdkreactnative/RNAdWhaleMediationAdView.java +60 -30
  10. package/android/src/main/java/com/adwhalesdkreactnative/RNAdWhaleMediationAppOpenAd.java +136 -0
  11. package/android/src/main/java/com/adwhalesdkreactnative/RNAdWhaleMediationCustomNativeAdView.java +37 -46
  12. package/android/src/main/java/com/adwhalesdkreactnative/RNAdWhaleMediationExitPopupAd.java +240 -0
  13. package/android/src/main/java/com/adwhalesdkreactnative/RNAdWhaleMediationInterstitialAd.java +189 -0
  14. package/android/src/main/java/com/adwhalesdkreactnative/RNAdWhaleMediationLoggerModule.java +2 -1
  15. package/android/src/main/java/com/adwhalesdkreactnative/RNAdWhaleMediationNativeAdViewListenerBridge.java +83 -0
  16. package/android/src/main/java/com/adwhalesdkreactnative/RNAdWhaleMediationRewardAd.java +255 -6
  17. package/android/src/main/java/com/adwhalesdkreactnative/RNAdWhaleMediationTemplateNativeAdView.java +191 -70
  18. package/android/src/main/java/com/adwhalesdkreactnative/RNAdWhaleMediationTransitionPopupAd.java +218 -0
  19. package/android/src/main/java/com/adwhalesdkreactnative/RNWrapperView.java +137 -0
  20. package/android/src/main/java/com/adwhalesdkreactnative/SimpleBinderFactory.java +1 -1
  21. package/android/src/main/java/com/adwhalesdkreactnative/common/RNMethodArgConst.java +112 -0
  22. package/android/src/main/java/com/adwhalesdkreactnative/common/RNMethodCallConst.java +113 -0
  23. package/android/src/main/java/com/adwhalesdkreactnative/common/RNMethodResultConst.java +28 -0
  24. package/build/generated/ios/ReactAppDependencyProvider.podspec +34 -0
  25. package/ios/AdWhaleNativeCustomViewFactoryRegistry.swift +56 -0
  26. package/ios/AdwhaleSdkReactNative.mm +96 -5
  27. package/ios/AdwhaleSdkReactNativeModule.swift +148 -0
  28. package/ios/RNAdWhaleMediationAdViewManager.m +38 -0
  29. package/ios/RNAdWhaleMediationAdViewManager.swift +14 -0
  30. package/ios/RNAdWhaleMediationAppOpenAd.m +18 -0
  31. package/ios/RNAdWhaleMediationAppOpenAd.swift +175 -0
  32. package/ios/RNAdWhaleMediationCustomNativeAdViewManager.m +22 -0
  33. package/ios/RNAdWhaleMediationCustomNativeAdViewManager.swift +239 -0
  34. package/ios/RNAdWhaleMediationInterstitialAd.m +18 -0
  35. package/ios/RNAdWhaleMediationInterstitialAd.swift +161 -0
  36. package/ios/RNAdWhaleMediationRewardAd.m +18 -0
  37. package/ios/RNAdWhaleMediationRewardAd.swift +172 -0
  38. package/ios/WhaleMediationBannerContainer.swift +182 -0
  39. package/lib/module/AdWhaleAdView.js +80 -1
  40. package/lib/module/AdWhaleAdView.js.map +1 -1
  41. package/lib/module/AdWhaleAppOpenAd.js +223 -25
  42. package/lib/module/AdWhaleAppOpenAd.js.map +1 -1
  43. package/lib/module/AdWhaleExitPopupAd.js +93 -0
  44. package/lib/module/AdWhaleExitPopupAd.js.map +1 -0
  45. package/lib/module/AdWhaleInterstitialAd.js +146 -22
  46. package/lib/module/AdWhaleInterstitialAd.js.map +1 -1
  47. package/lib/module/AdWhaleMediationAds.js +75 -4
  48. package/lib/module/AdWhaleMediationAds.js.map +1 -1
  49. package/lib/module/AdWhaleNativeCustomView.js +59 -8
  50. package/lib/module/AdWhaleNativeCustomView.js.map +1 -1
  51. package/lib/module/AdWhaleNativeTemplateView.js +37 -19
  52. package/lib/module/AdWhaleNativeTemplateView.js.map +1 -1
  53. package/lib/module/AdWhaleRewardAd.js +169 -24
  54. package/lib/module/AdWhaleRewardAd.js.map +1 -1
  55. package/lib/module/AdWhaleTransitionPopupAd.js +87 -0
  56. package/lib/module/AdWhaleTransitionPopupAd.js.map +1 -0
  57. package/lib/module/NativeAdwhaleSdkReactNative.js +16 -1
  58. package/lib/module/NativeAdwhaleSdkReactNative.js.map +1 -1
  59. package/lib/module/constants/AdWhaleMethodArgConst.js +53 -0
  60. package/lib/module/constants/AdWhaleMethodArgConst.js.map +1 -0
  61. package/lib/module/constants/AdWhaleMethodCallConst.js +56 -0
  62. package/lib/module/constants/AdWhaleMethodCallConst.js.map +1 -0
  63. package/lib/module/constants/AdWhaleMethodResultConst.js +16 -0
  64. package/lib/module/constants/AdWhaleMethodResultConst.js.map +1 -0
  65. package/lib/module/index.js +10 -1
  66. package/lib/module/index.js.map +1 -1
  67. package/lib/typescript/src/AdWhaleAdView.d.ts +46 -2
  68. package/lib/typescript/src/AdWhaleAdView.d.ts.map +1 -1
  69. package/lib/typescript/src/AdWhaleAppOpenAd.d.ts +10 -0
  70. package/lib/typescript/src/AdWhaleAppOpenAd.d.ts.map +1 -1
  71. package/lib/typescript/src/AdWhaleExitPopupAd.d.ts +36 -0
  72. package/lib/typescript/src/AdWhaleExitPopupAd.d.ts.map +1 -0
  73. package/lib/typescript/src/AdWhaleInterstitialAd.d.ts +16 -0
  74. package/lib/typescript/src/AdWhaleInterstitialAd.d.ts.map +1 -1
  75. package/lib/typescript/src/AdWhaleMediationAds.d.ts +14 -5
  76. package/lib/typescript/src/AdWhaleMediationAds.d.ts.map +1 -1
  77. package/lib/typescript/src/AdWhaleNativeCustomView.d.ts +7 -4
  78. package/lib/typescript/src/AdWhaleNativeCustomView.d.ts.map +1 -1
  79. package/lib/typescript/src/AdWhaleNativeTemplateView.d.ts +20 -7
  80. package/lib/typescript/src/AdWhaleNativeTemplateView.d.ts.map +1 -1
  81. package/lib/typescript/src/AdWhaleRewardAd.d.ts +18 -2
  82. package/lib/typescript/src/AdWhaleRewardAd.d.ts.map +1 -1
  83. package/lib/typescript/src/AdWhaleTransitionPopupAd.d.ts +33 -0
  84. package/lib/typescript/src/AdWhaleTransitionPopupAd.d.ts.map +1 -0
  85. package/lib/typescript/src/NativeAdwhaleSdkReactNative.d.ts +33 -6
  86. package/lib/typescript/src/NativeAdwhaleSdkReactNative.d.ts.map +1 -1
  87. package/lib/typescript/src/constants/AdWhaleMethodArgConst.d.ts +51 -0
  88. package/lib/typescript/src/constants/AdWhaleMethodArgConst.d.ts.map +1 -0
  89. package/lib/typescript/src/constants/AdWhaleMethodCallConst.d.ts +53 -0
  90. package/lib/typescript/src/constants/AdWhaleMethodCallConst.d.ts.map +1 -0
  91. package/lib/typescript/src/constants/AdWhaleMethodResultConst.d.ts +14 -0
  92. package/lib/typescript/src/constants/AdWhaleMethodResultConst.d.ts.map +1 -0
  93. package/lib/typescript/src/index.d.ts +10 -2
  94. package/lib/typescript/src/index.d.ts.map +1 -1
  95. package/package.json +1 -1
  96. package/src/AdWhaleAdView.tsx +126 -9
  97. package/src/AdWhaleAppOpenAd.ts +293 -38
  98. package/src/AdWhaleExitPopupAd.ts +183 -0
  99. package/src/AdWhaleInterstitialAd.ts +206 -36
  100. package/src/AdWhaleMediationAds.ts +109 -5
  101. package/src/AdWhaleNativeCustomView.tsx +85 -23
  102. package/src/AdWhaleNativeTemplateView.tsx +79 -42
  103. package/src/AdWhaleRewardAd.ts +245 -43
  104. package/src/AdWhaleTransitionPopupAd.ts +171 -0
  105. package/src/NativeAdwhaleSdkReactNative.ts +36 -6
  106. package/src/constants/AdWhaleMethodArgConst.ts +50 -0
  107. package/src/constants/AdWhaleMethodCallConst.ts +60 -0
  108. package/src/constants/AdWhaleMethodResultConst.ts +13 -0
  109. package/src/index.ts +34 -1
@@ -22,20 +22,34 @@ export interface AdWhaleAppOpenAdGcoder {
22
22
  }
23
23
 
24
24
  interface RNAdWhaleMediationAppOpenAdNativeModule {
25
- setPlacementName(placementName: string): void;
26
- setRegion(region: string): void;
27
- setGcoder(gcoder: { lt: number; lng: number }): void;
28
- loadAd(placementUid: string): void;
29
- showAd(): void;
25
+ setPlacementName?(placementName: string): void;
26
+ setRegion?(region: string): void;
27
+ setGcoder?(gcoder: { lt: number; lng: number }): void;
28
+ loadAd?(placementUid: string): void;
29
+ showAd?(): void;
30
+ loadAppOpenAd?(args: {
31
+ adId: number;
32
+ placementUid: string;
33
+ placementName?: string;
34
+ region?: string;
35
+ gcoder?: [number, number];
36
+ }): void;
37
+ showAdWithoutView?(adId: number): void;
38
+ destroyAd?(adId: number): void;
30
39
  addListener(eventName: string): void;
31
40
  removeListeners(count: number): void;
32
41
  }
33
42
 
43
+ const LINKING_ERROR =
44
+ 'RNAdWhaleMediationAppOpenAd native module is not linked on this platform.';
45
+
34
46
  const { RNAdWhaleMediationAppOpenAd } = NativeModules as {
35
- RNAdWhaleMediationAppOpenAd: RNAdWhaleMediationAppOpenAdNativeModule;
47
+ RNAdWhaleMediationAppOpenAd?: RNAdWhaleMediationAppOpenAdNativeModule;
36
48
  };
37
49
 
38
- const appOpenEmitter = new NativeEventEmitter(RNAdWhaleMediationAppOpenAd);
50
+ const appOpenEmitter = RNAdWhaleMediationAppOpenAd
51
+ ? new NativeEventEmitter(RNAdWhaleMediationAppOpenAd)
52
+ : null;
39
53
 
40
54
  export const AdWhaleAppOpenAd = {
41
55
  loadAd(
@@ -46,71 +60,312 @@ export const AdWhaleAppOpenAd = {
46
60
  gcoder?: AdWhaleAppOpenAdGcoder;
47
61
  },
48
62
  ) {
63
+ if (!RNAdWhaleMediationAppOpenAd) {
64
+ console.warn(LINKING_ERROR);
65
+ return;
66
+ }
49
67
  // 먼저 옵션들을 설정
50
68
  if (options?.placementName) {
51
- RNAdWhaleMediationAppOpenAd.setPlacementName(options.placementName);
69
+ RNAdWhaleMediationAppOpenAd.setPlacementName?.(options.placementName);
52
70
  }
53
71
  if (options?.region) {
54
- RNAdWhaleMediationAppOpenAd.setRegion(options.region);
72
+ RNAdWhaleMediationAppOpenAd.setRegion?.(options.region);
55
73
  }
56
74
  if (options?.gcoder) {
57
- RNAdWhaleMediationAppOpenAd.setGcoder(options.gcoder);
75
+ RNAdWhaleMediationAppOpenAd.setGcoder?.(options.gcoder);
76
+ }
77
+ if (RNAdWhaleMediationAppOpenAd.loadAd) {
78
+ RNAdWhaleMediationAppOpenAd.loadAd(placementUid);
79
+ return;
80
+ }
81
+ if (RNAdWhaleMediationAppOpenAd.loadAppOpenAd) {
82
+ RNAdWhaleMediationAppOpenAd.loadAppOpenAd({
83
+ adId: 0,
84
+ placementUid,
85
+ placementName: options?.placementName,
86
+ region: options?.region,
87
+ gcoder: options?.gcoder
88
+ ? [options.gcoder.lt, options.gcoder.lng]
89
+ : undefined,
90
+ });
91
+ return;
58
92
  }
59
- // 그 다음 loadAd 호출
60
- RNAdWhaleMediationAppOpenAd.loadAd(placementUid);
93
+ console.warn(
94
+ '[AdWhaleAppOpenAd] Native module missing both loadAd and loadAppOpenAd.',
95
+ );
61
96
  },
62
97
 
63
98
  showAd() {
64
- RNAdWhaleMediationAppOpenAd.showAd();
99
+ if (!RNAdWhaleMediationAppOpenAd) {
100
+ console.warn(LINKING_ERROR);
101
+ return;
102
+ }
103
+ if (RNAdWhaleMediationAppOpenAd.showAd) {
104
+ RNAdWhaleMediationAppOpenAd.showAd();
105
+ return;
106
+ }
107
+ if (RNAdWhaleMediationAppOpenAd.showAdWithoutView) {
108
+ RNAdWhaleMediationAppOpenAd.showAdWithoutView(0);
109
+ return;
110
+ }
111
+ console.warn(
112
+ '[AdWhaleAppOpenAd] Native module missing both showAd and showAdWithoutView.',
113
+ );
114
+ },
115
+
116
+ /** Flutter와 동일한 신규 API (권장) */
117
+ loadAppOpenAd(
118
+ adId: number,
119
+ placementUid: string,
120
+ options?: {
121
+ placementName?: string;
122
+ region?: string;
123
+ gcoder?: AdWhaleAppOpenAdGcoder;
124
+ },
125
+ ) {
126
+ if (!RNAdWhaleMediationAppOpenAd) {
127
+ console.warn(LINKING_ERROR);
128
+ return;
129
+ }
130
+ if (!RNAdWhaleMediationAppOpenAd.loadAppOpenAd) {
131
+ this.loadAd(placementUid, options);
132
+ return;
133
+ }
134
+ RNAdWhaleMediationAppOpenAd.loadAppOpenAd({
135
+ adId,
136
+ placementUid,
137
+ placementName: options?.placementName,
138
+ region: options?.region,
139
+ gcoder: options?.gcoder ? [options.gcoder.lt, options.gcoder.lng] : undefined,
140
+ });
141
+ },
142
+
143
+ showAdWithoutView(adId: number) {
144
+ if (!RNAdWhaleMediationAppOpenAd) {
145
+ console.warn(LINKING_ERROR);
146
+ return;
147
+ }
148
+ if (!RNAdWhaleMediationAppOpenAd.showAdWithoutView) {
149
+ this.showAd();
150
+ return;
151
+ }
152
+ RNAdWhaleMediationAppOpenAd.showAdWithoutView(adId);
153
+ },
154
+
155
+ destroyAd(adId: number) {
156
+ RNAdWhaleMediationAppOpenAd?.destroyAd?.(adId);
65
157
  },
66
158
 
67
159
  addEventListeners(listeners: AdWhaleAppOpenEvents): EmitterSubscription[] {
160
+ if (!appOpenEmitter) {
161
+ console.warn(LINKING_ERROR);
162
+ return [];
163
+ }
68
164
  const subs: EmitterSubscription[] = [];
69
-
70
- if (listeners.onLoaded) {
71
- subs.push(
72
- appOpenEmitter.addListener('onAppOpenAdLoaded', () => {
73
- listeners.onLoaded?.();
74
- }),
165
+ let lastDirectEvent: { name: string; timeMs: number } | null = null;
166
+ const markDirectEvent = (name: string) => {
167
+ lastDirectEvent = { name, timeMs: Date.now() };
168
+ };
169
+ const isDuplicatedFromDirect = (name: string) => {
170
+ if (!lastDirectEvent) {
171
+ return false;
172
+ }
173
+ return (
174
+ lastDirectEvent.name === name &&
175
+ Date.now() - lastDirectEvent.timeMs < 1000
75
176
  );
76
- }
177
+ };
178
+
179
+ subs.push(
180
+ appOpenEmitter.addListener('onAppOpenAdLoaded', () => {
181
+ markDirectEvent('onAppOpenAdLoaded');
182
+ console.log('AdWhaleAppOpenAd.ts AppOpen onLoaded');
183
+ listeners.onLoaded?.();
184
+ }),
185
+ );
77
186
  if (listeners.onLoadFailed) {
78
187
  subs.push(
79
188
  appOpenEmitter.addListener(
80
189
  'onAppOpenAdFailedToLoad',
81
- event => listeners.onLoadFailed?.(event as AdWhaleAppOpenErrorEvent),
190
+ event => {
191
+ markDirectEvent('onAppOpenAdFailedToLoad');
192
+ const appOpenError = event as AdWhaleAppOpenErrorEvent;
193
+ console.log(
194
+ `AdWhaleAppOpenAd.ts AppOpen onAppOpenAdFailedToLoad: ${appOpenError.statusCode}, ${appOpenError.message}`,
195
+ );
196
+ listeners.onLoadFailed?.(appOpenError);
197
+ },
82
198
  ),
83
199
  );
84
200
  }
85
- if (listeners.onShowed) {
86
- subs.push(
87
- appOpenEmitter.addListener('onAppOpenAdShowed', () => {
88
- listeners.onShowed?.();
89
- }),
90
- );
91
- }
201
+ subs.push(
202
+ appOpenEmitter.addListener('onAppOpenAdShowed', () => {
203
+ markDirectEvent('onAppOpenAdShowed');
204
+ console.log('AdWhaleAppOpenAd.ts AppOpen onAdShowed');
205
+ listeners.onShowed?.();
206
+ }),
207
+ );
92
208
  if (listeners.onShowFailed) {
93
209
  subs.push(
94
210
  appOpenEmitter.addListener(
95
211
  'onAppOpenAdFailedToShow',
96
- event => listeners.onShowFailed?.(event as AdWhaleAppOpenErrorEvent),
212
+ event => {
213
+ markDirectEvent('onAppOpenAdFailedToShow');
214
+ const appOpenError = event as AdWhaleAppOpenErrorEvent;
215
+ console.log(
216
+ `AdWhaleAppOpenAd.ts AppOpen onAppOpenAdFailedToShow: ${appOpenError.statusCode}, ${appOpenError.message}`,
217
+ );
218
+ listeners.onShowFailed?.(appOpenError);
219
+ },
97
220
  ),
98
221
  );
99
222
  }
100
- if (listeners.onDismissed) {
101
- subs.push(
102
- appOpenEmitter.addListener('onAppOpenAdDismissed', () => {
223
+ subs.push(
224
+ appOpenEmitter.addListener('onAppOpenAdDismissed', () => {
225
+ markDirectEvent('onAppOpenAdDismissed');
226
+ console.log('AdWhaleAppOpenAd.ts AppOpen onAdDismissed');
227
+ listeners.onDismissed?.();
228
+ }),
229
+ );
230
+ subs.push(
231
+ appOpenEmitter.addListener('onAppOpenAdClicked', () => {
232
+ markDirectEvent('onAppOpenAdClicked');
233
+ console.log('AdWhaleAppOpenAd.ts AppOpen onAppOpenAdClicked');
234
+ listeners.onClicked?.();
235
+ }),
236
+ );
237
+ subs.push(
238
+ appOpenEmitter.addListener('onAdEvent', (payload: any) => {
239
+ const eventName = payload?.eventName as string | undefined;
240
+ if (!eventName || isDuplicatedFromDirect(eventName)) {
241
+ return;
242
+ }
243
+ if (eventName === 'onAppOpenAdLoaded') {
244
+ console.log('AdWhaleAppOpenAd.ts AppOpen onLoaded');
245
+ listeners.onLoaded?.();
246
+ return;
247
+ }
248
+ if (eventName === 'onAppOpenAdShowed') {
249
+ console.log('AdWhaleAppOpenAd.ts AppOpen onAdShowed');
250
+ listeners.onShowed?.();
251
+ return;
252
+ }
253
+ if (eventName === 'onAppOpenAdDismissed') {
254
+ console.log('AdWhaleAppOpenAd.ts AppOpen onAdDismissed');
103
255
  listeners.onDismissed?.();
104
- }),
105
- );
256
+ return;
257
+ }
258
+ if (eventName === 'onAppOpenAdFailedToLoad') {
259
+ const appOpenError = {
260
+ statusCode: Number(payload?.statusCode ?? -1),
261
+ message: String(payload?.message ?? ''),
262
+ };
263
+ console.log(
264
+ `AdWhaleAppOpenAd.ts AppOpen onAppOpenAdFailedToLoad: ${appOpenError.statusCode}, ${appOpenError.message}`,
265
+ );
266
+ listeners.onLoadFailed?.(appOpenError);
267
+ return;
268
+ }
269
+ if (eventName === 'onAppOpenAdFailedToShow') {
270
+ const appOpenError = {
271
+ statusCode: Number(payload?.statusCode ?? -1),
272
+ message: String(payload?.message ?? ''),
273
+ };
274
+ console.log(
275
+ `AdWhaleAppOpenAd.ts AppOpen onAppOpenAdFailedToShow: ${appOpenError.statusCode}, ${appOpenError.message}`,
276
+ );
277
+ listeners.onShowFailed?.(appOpenError);
278
+ return;
279
+ }
280
+ if (eventName === 'onAppOpenAdClicked') {
281
+ console.log('AdWhaleAppOpenAd.ts AppOpen onAppOpenAdClicked');
282
+ listeners.onClicked?.();
283
+ }
284
+ }),
285
+ );
286
+
287
+ return subs;
288
+ },
289
+
290
+ /** Flutter `onAdEvent` 스타일 (adId 필터링) */
291
+ addAdEventListenersById(
292
+ adId: number,
293
+ listeners: AdWhaleAppOpenEvents,
294
+ ): EmitterSubscription[] {
295
+ if (!appOpenEmitter) {
296
+ console.warn(LINKING_ERROR);
297
+ return [];
106
298
  }
107
- if (listeners.onClicked) {
299
+ const subs: EmitterSubscription[] = [];
300
+
301
+ const handle = (eventName: string, cb?: (p?: any) => void) => {
302
+ if (!cb) return;
108
303
  subs.push(
109
- appOpenEmitter.addListener('onAppOpenAdClicked', () => {
110
- listeners.onClicked?.();
304
+ appOpenEmitter.addListener('onAdEvent', (payload: any) => {
305
+ if (!payload || payload.adId !== adId || payload.eventName !== eventName) {
306
+ return;
307
+ }
308
+ cb(payload);
111
309
  }),
112
310
  );
113
- }
311
+ };
312
+
313
+ handle('onAppOpenAdLoaded', () => {
314
+ console.log('AdWhaleAppOpenAd.ts AppOpen onLoaded');
315
+ listeners.onLoaded?.();
316
+ });
317
+ handle('onAppOpenAdLoadFailed', p => {
318
+ const appOpenError = {
319
+ statusCode: Number(p?.statusCode ?? -1),
320
+ message: String(p?.message ?? ''),
321
+ };
322
+ console.log(
323
+ `AdWhaleAppOpenAd.ts AppOpen onAppOpenAdFailedToLoad: ${appOpenError.statusCode}, ${appOpenError.message}`,
324
+ );
325
+ listeners.onLoadFailed?.(appOpenError);
326
+ });
327
+ handle('onAppOpenAdFailedToLoad', p => {
328
+ const appOpenError = {
329
+ statusCode: Number(p?.statusCode ?? -1),
330
+ message: String(p?.message ?? ''),
331
+ };
332
+ console.log(
333
+ `AdWhaleAppOpenAd.ts AppOpen onAppOpenAdFailedToLoad: ${appOpenError.statusCode}, ${appOpenError.message}`,
334
+ );
335
+ listeners.onLoadFailed?.(appOpenError);
336
+ });
337
+ handle('onAppOpenAdShowed', () => {
338
+ console.log('AdWhaleAppOpenAd.ts AppOpen onAdShowed');
339
+ listeners.onShowed?.();
340
+ });
341
+ handle('onAppOpenAdShowFailed', p => {
342
+ const appOpenError = {
343
+ statusCode: Number(p?.statusCode ?? -1),
344
+ message: String(p?.message ?? ''),
345
+ };
346
+ console.log(
347
+ `AdWhaleAppOpenAd.ts AppOpen onAppOpenAdFailedToShow: ${appOpenError.statusCode}, ${appOpenError.message}`,
348
+ );
349
+ listeners.onShowFailed?.(appOpenError);
350
+ });
351
+ handle('onAppOpenAdFailedToShow', p => {
352
+ const appOpenError = {
353
+ statusCode: Number(p?.statusCode ?? -1),
354
+ message: String(p?.message ?? ''),
355
+ };
356
+ console.log(
357
+ `AdWhaleAppOpenAd.ts AppOpen onAppOpenAdFailedToShow: ${appOpenError.statusCode}, ${appOpenError.message}`,
358
+ );
359
+ listeners.onShowFailed?.(appOpenError);
360
+ });
361
+ handle('onAppOpenAdDismissed', () => {
362
+ console.log('AdWhaleAppOpenAd.ts AppOpen onAdDismissed');
363
+ listeners.onDismissed?.();
364
+ });
365
+ handle('onAppOpenAdClicked', () => {
366
+ console.log('AdWhaleAppOpenAd.ts AppOpen onAppOpenAdClicked');
367
+ listeners.onClicked?.();
368
+ });
114
369
 
115
370
  return subs;
116
371
  },
@@ -0,0 +1,183 @@
1
+ // src/AdWhaleExitPopupAd.ts
2
+ import {
3
+ NativeEventEmitter,
4
+ NativeModules,
5
+ Platform,
6
+ } from 'react-native';
7
+ import type { EmitterSubscription } from 'react-native';
8
+
9
+ export interface AdWhaleExitPopupAdErrorEvent {
10
+ statusCode: number;
11
+ message: string;
12
+ }
13
+
14
+ export interface AdWhaleExitPopupAdClosedEvent {
15
+ reasonId: number;
16
+ reasonMessage: string;
17
+ }
18
+
19
+ export interface AdWhaleExitPopupAdEvents {
20
+ onLoaded?: () => void;
21
+ onLoadFailed?: (event: AdWhaleExitPopupAdErrorEvent) => void;
22
+ onShowed?: () => void;
23
+ onShowFailed?: (event: AdWhaleExitPopupAdErrorEvent) => void;
24
+ onClicked?: () => void;
25
+ onClosed?: (event: AdWhaleExitPopupAdClosedEvent) => void;
26
+ }
27
+
28
+ export interface AdWhaleExitPopupGcoder {
29
+ lt: number;
30
+ lng: number;
31
+ }
32
+
33
+ interface RNAdWhaleMediationExitPopupAdNativeModule {
34
+ setPlacementName(placementName: string): void;
35
+ setRegion(region: string): void;
36
+ setGcoder(gcoder: { lt: number; lng: number }): void;
37
+ setCustomizeButtonText(
38
+ primaryButtonText: string,
39
+ secondaryButtonText: string
40
+ ): void;
41
+ setCustomDescription(descriptionText: string): void;
42
+ loadAd(placementUid: string): void;
43
+ showAd(): void;
44
+ destroy(): void;
45
+ resume(): void;
46
+ addListener(eventName: string): void;
47
+ removeListeners(count: number): void;
48
+ }
49
+
50
+ const LINKING_ERROR =
51
+ Platform.OS === 'android'
52
+ ? 'RNAdWhaleMediationExitPopupAd native module is not linked.'
53
+ : 'Exit Popup Ad is only supported on Android.';
54
+
55
+ const { RNAdWhaleMediationExitPopupAd } = NativeModules as {
56
+ RNAdWhaleMediationExitPopupAd?: RNAdWhaleMediationExitPopupAdNativeModule;
57
+ };
58
+
59
+ const exitPopupEmitter = RNAdWhaleMediationExitPopupAd
60
+ ? new NativeEventEmitter(RNAdWhaleMediationExitPopupAd)
61
+ : null;
62
+
63
+ export const AdWhaleExitPopupAd = {
64
+ loadAd(
65
+ placementUid: string,
66
+ options?: {
67
+ placementName?: string;
68
+ region?: string;
69
+ gcoder?: AdWhaleExitPopupGcoder;
70
+ primaryButtonText?: string;
71
+ secondaryButtonText?: string;
72
+ descriptionText?: string;
73
+ }
74
+ ) {
75
+ if (!RNAdWhaleMediationExitPopupAd) {
76
+ console.warn(LINKING_ERROR);
77
+ return;
78
+ }
79
+ if (options?.placementName != null) {
80
+ RNAdWhaleMediationExitPopupAd.setPlacementName(options.placementName);
81
+ }
82
+ if (options?.region != null) {
83
+ RNAdWhaleMediationExitPopupAd.setRegion(options.region);
84
+ }
85
+ if (options?.gcoder) {
86
+ RNAdWhaleMediationExitPopupAd.setGcoder(options.gcoder);
87
+ }
88
+ if (
89
+ options?.primaryButtonText != null ||
90
+ options?.secondaryButtonText != null
91
+ ) {
92
+ RNAdWhaleMediationExitPopupAd.setCustomizeButtonText(
93
+ options.primaryButtonText ?? '',
94
+ options.secondaryButtonText ?? ''
95
+ );
96
+ }
97
+ if (options?.descriptionText != null) {
98
+ RNAdWhaleMediationExitPopupAd.setCustomDescription(
99
+ options.descriptionText
100
+ );
101
+ }
102
+ RNAdWhaleMediationExitPopupAd.loadAd(placementUid);
103
+ },
104
+
105
+ showAd() {
106
+ if (!RNAdWhaleMediationExitPopupAd) {
107
+ console.warn(LINKING_ERROR);
108
+ return;
109
+ }
110
+ RNAdWhaleMediationExitPopupAd.showAd();
111
+ },
112
+
113
+ destroy() {
114
+ if (!RNAdWhaleMediationExitPopupAd) {
115
+ console.warn(LINKING_ERROR);
116
+ return;
117
+ }
118
+ RNAdWhaleMediationExitPopupAd.destroy();
119
+ },
120
+
121
+ resume() {
122
+ if (!RNAdWhaleMediationExitPopupAd) {
123
+ console.warn(LINKING_ERROR);
124
+ return;
125
+ }
126
+ RNAdWhaleMediationExitPopupAd.resume();
127
+ },
128
+
129
+ addEventListeners(
130
+ listeners: AdWhaleExitPopupAdEvents
131
+ ): EmitterSubscription[] {
132
+ if (!exitPopupEmitter) {
133
+ console.warn(LINKING_ERROR);
134
+ return [];
135
+ }
136
+ const subs: EmitterSubscription[] = [];
137
+
138
+ if (listeners.onLoaded) {
139
+ subs.push(
140
+ exitPopupEmitter.addListener('onExitPopupAdLoaded', () => {
141
+ listeners.onLoaded?.();
142
+ })
143
+ );
144
+ }
145
+ if (listeners.onLoadFailed) {
146
+ subs.push(
147
+ exitPopupEmitter.addListener('onExitPopupAdLoadFailed', event => {
148
+ listeners.onLoadFailed?.(event as AdWhaleExitPopupAdErrorEvent);
149
+ })
150
+ );
151
+ }
152
+ if (listeners.onShowed) {
153
+ subs.push(
154
+ exitPopupEmitter.addListener('onExitPopupAdShowed', () => {
155
+ listeners.onShowed?.();
156
+ })
157
+ );
158
+ }
159
+ if (listeners.onShowFailed) {
160
+ subs.push(
161
+ exitPopupEmitter.addListener('onExitPopupAdShowFailed', event => {
162
+ listeners.onShowFailed?.(event as AdWhaleExitPopupAdErrorEvent);
163
+ })
164
+ );
165
+ }
166
+ if (listeners.onClicked) {
167
+ subs.push(
168
+ exitPopupEmitter.addListener('onExitPopupAdClicked', () => {
169
+ listeners.onClicked?.();
170
+ })
171
+ );
172
+ }
173
+ if (listeners.onClosed) {
174
+ subs.push(
175
+ exitPopupEmitter.addListener('onExitPopupAdClosed', event => {
176
+ listeners.onClosed?.(event as AdWhaleExitPopupAdClosedEvent);
177
+ })
178
+ );
179
+ }
180
+
181
+ return subs;
182
+ },
183
+ };