adwhale-sdk-react-native 2.7.204 → 2.7.400

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 +95 -91
  3. package/android/build.gradle +35 -1
  4. package/android/proguard-rules.pro +58 -0
  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 +148 -49
  9. package/android/src/main/java/com/adwhalesdkreactnative/RNAdWhaleMediationAdView.java +46 -27
  10. package/android/src/main/java/com/adwhalesdkreactnative/RNAdWhaleMediationAppOpenAd.java +148 -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 +205 -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 +341 -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 +22 -0
  37. package/ios/RNAdWhaleMediationRewardAd.swift +206 -0
  38. package/ios/WhaleMediationBannerContainer.swift +182 -0
  39. package/lib/module/AdWhaleAdView.js +58 -3
  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 +221 -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 +20 -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 +13 -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 +63 -6
  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 +28 -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 +92 -4
  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 +108 -4
  101. package/src/AdWhaleNativeCustomView.tsx +85 -23
  102. package/src/AdWhaleNativeTemplateView.tsx +79 -42
  103. package/src/AdWhaleRewardAd.ts +317 -51
  104. package/src/AdWhaleTransitionPopupAd.ts +171 -0
  105. package/src/NativeAdwhaleSdkReactNative.ts +30 -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 +35 -0
@@ -11,6 +11,8 @@ import com.facebook.react.bridge.ReactContextBaseJavaModule;
11
11
  import com.facebook.react.bridge.ReactMethod;
12
12
  import com.facebook.react.bridge.ReadableMap;
13
13
  import com.facebook.react.bridge.UiThreadUtil;
14
+ import com.facebook.react.bridge.ReadableType;
15
+ import com.facebook.react.bridge.ReadableArray;
14
16
  import com.facebook.react.bridge.WritableMap;
15
17
  import com.facebook.react.modules.core.DeviceEventManagerModule;
16
18
 
@@ -27,6 +29,13 @@ import java.util.Map;
27
29
  public class RNAdWhaleMediationInterstitialAd extends ReactContextBaseJavaModule implements AdWhaleMediationInterstitialAdListener {
28
30
 
29
31
  public static final String REACT_CLASS_NAME = RNAdWhaleMediationInterstitialAd.class.getSimpleName();
32
+
33
+ // Flutter와 싱크: adId 기반 멀티 인스턴스 지원 (RN에서도 여러 placement 동시 운용 가능)
34
+ private final Map<Integer, AdWhaleMediationInterstitialAd> adsById = new HashMap<>();
35
+
36
+ // 마지막으로 콜백이 발생한 광고 id (SDK Listener가 adId를 직접 주지 않아서 우회)
37
+ private int lastActiveAdId = 0;
38
+
30
39
  private AdWhaleMediationInterstitialAd adWhaleMediationInterstitialAd;
31
40
  private String placementUid;
32
41
  private String placementName;
@@ -72,6 +81,8 @@ public class RNAdWhaleMediationInterstitialAd extends ReactContextBaseJavaModule
72
81
  @ReactMethod
73
82
  public void loadAd(String placementUid) {
74
83
  Log.e(REACT_CLASS_NAME, ".loadAd()");
84
+ // 싱글턴 load 경로: onAdEvent(adId) 는 0으로 고정 (멀티 로드 후 lastActiveAdId 오염 방지)
85
+ lastActiveAdId = 0;
75
86
  this.placementUid = placementUid;
76
87
  adWhaleMediationInterstitialAd = new AdWhaleMediationInterstitialAd(placementUid);
77
88
  adWhaleMediationInterstitialAd.setAdWhaleMediationInterstitialAdListener(this);
@@ -84,6 +95,69 @@ public class RNAdWhaleMediationInterstitialAd extends ReactContextBaseJavaModule
84
95
  });
85
96
  }
86
97
 
98
+ /**
99
+ * Flutter MethodChannel과 동일 네이밍:
100
+ * loadInterstitialAd({adId, placementUid, region, gcoder:[lt,lng], placementName})
101
+ */
102
+ @ReactMethod
103
+ public void loadInterstitialAd(ReadableMap args) {
104
+ if (args == null) {
105
+ Log.e(REACT_CLASS_NAME, "loadInterstitialAd args is null");
106
+ return;
107
+ }
108
+ if (!args.hasKey("adId") || args.getType("adId") != ReadableType.Number) {
109
+ Log.e(REACT_CLASS_NAME, "loadInterstitialAd missing adId (number)");
110
+ return;
111
+ }
112
+ if (!args.hasKey("placementUid") || args.getType("placementUid") != ReadableType.String) {
113
+ Log.e(REACT_CLASS_NAME, "loadInterstitialAd missing placementUid (string)");
114
+ return;
115
+ }
116
+ final int adId = args.getInt("adId");
117
+ final String placementUid = args.getString("placementUid");
118
+
119
+ final AdWhaleMediationInterstitialAd interstitialAd = new AdWhaleMediationInterstitialAd(placementUid);
120
+ // 멀티 인스턴스: 인스턴스마다 adId를 캡처한 리스너 (공유 this + lastActiveAdId 는 경합으로 마지막 id만 남음)
121
+ interstitialAd.setAdWhaleMediationInterstitialAdListener(new PerAdInterstitialListener(adId));
122
+
123
+ try {
124
+ if (args.hasKey("region") && args.getType("region") == ReadableType.String) {
125
+ String r = args.getString("region");
126
+ if (r != null && !r.isEmpty()) interstitialAd.setRegion(r);
127
+ }
128
+ } catch (Throwable t) {
129
+ Log.w(REACT_CLASS_NAME, "setRegion failed: " + t.getMessage());
130
+ }
131
+
132
+ try {
133
+ if (args.hasKey("placementName") && args.getType("placementName") == ReadableType.String) {
134
+ String pn = args.getString("placementName");
135
+ if (pn != null && !pn.isEmpty()) interstitialAd.setPlacementName(pn);
136
+ }
137
+ } catch (Throwable t) {
138
+ Log.w(REACT_CLASS_NAME, "setPlacementName failed: " + t.getMessage());
139
+ }
140
+
141
+ try {
142
+ if (args.hasKey("gcoder") && args.getType("gcoder") == ReadableType.Array) {
143
+ ReadableArray arr = args.getArray("gcoder");
144
+ if (arr != null && arr.size() >= 2
145
+ && arr.getType(0) == ReadableType.Number
146
+ && arr.getType(1) == ReadableType.Number) {
147
+ double lat = arr.getDouble(0);
148
+ double lng = arr.getDouble(1);
149
+ interstitialAd.setGcoder(lat, lng);
150
+ }
151
+ }
152
+ } catch (Throwable t) {
153
+ Log.w(REACT_CLASS_NAME, "setGcoder failed: " + t.getMessage());
154
+ }
155
+
156
+ adsById.put(adId, interstitialAd);
157
+
158
+ UiThreadUtil.runOnUiThread(interstitialAd::loadAd);
159
+ }
160
+
87
161
  @ReactMethod
88
162
  public void showAd() {
89
163
  Log.e(REACT_CLASS_NAME, "showAd()");
@@ -92,15 +166,42 @@ public class RNAdWhaleMediationInterstitialAd extends ReactContextBaseJavaModule
92
166
  return;
93
167
  }
94
168
 
169
+ lastActiveAdId = 0;
95
170
  UiThreadUtil.runOnUiThread(() -> {
96
171
  adWhaleMediationInterstitialAd.showAd();
97
172
  });
98
173
  }
99
174
 
175
+ /** Flutter 네이밍: showAdWithoutView(adId) */
176
+ @ReactMethod
177
+ public void showAdWithoutView(int adId) {
178
+ AdWhaleMediationInterstitialAd ad = adsById.get(adId);
179
+ if (ad == null) {
180
+ Log.e(REACT_CLASS_NAME, "showAdWithoutView: ad not found. adId=" + adId);
181
+ return;
182
+ }
183
+ lastActiveAdId = adId;
184
+ UiThreadUtil.runOnUiThread(ad::showAd);
185
+ }
186
+
187
+ /** Flutter 네이밍: destroyAd(adId) */
188
+ @ReactMethod
189
+ public void destroyAd(int adId) {
190
+ AdWhaleMediationInterstitialAd ad = adsById.remove(adId);
191
+ if (ad != null) {
192
+ try {
193
+ ad.destroy();
194
+ } catch (Throwable t) {
195
+ Log.w(REACT_CLASS_NAME, "destroyAd failed: " + t.getMessage());
196
+ }
197
+ }
198
+ }
199
+
100
200
  @Override
101
201
  public void onAdLoaded() {
102
202
  Log.i(REACT_CLASS_NAME, "onAdLoaded()");
103
203
  sendEvent("onInterstitialAdLoaded", null);
204
+ sendAdEvent(lastActiveAdId, "onInterstitialAdLoaded", null);
104
205
 
105
206
  }
106
207
 
@@ -111,12 +212,18 @@ public class RNAdWhaleMediationInterstitialAd extends ReactContextBaseJavaModule
111
212
  params.putInt("statusCode", statusCode);
112
213
  params.putString("message", message);
113
214
  sendEvent("onInterstitialAdLoadFailed", params);
215
+ // NOTE: emit() 이후에는 Map 이 consume 되므로 재사용 금지. 새 맵으로 따로 보낸다.
216
+ WritableMap forAdEvent = Arguments.createMap();
217
+ forAdEvent.putInt("statusCode", statusCode);
218
+ forAdEvent.putString("message", message);
219
+ sendAdEvent(lastActiveAdId, "onInterstitialAdLoadFailed", forAdEvent);
114
220
  }
115
221
 
116
222
  @Override
117
223
  public void onAdShowed() {
118
224
  Log.i(REACT_CLASS_NAME, "onAdShowed()");
119
225
  sendEvent("onInterstitialAdShowed", null);
226
+ sendAdEvent(lastActiveAdId, "onInterstitialAdShowed", null);
120
227
  }
121
228
 
122
229
  @Override
@@ -126,18 +233,30 @@ public class RNAdWhaleMediationInterstitialAd extends ReactContextBaseJavaModule
126
233
  params.putInt("statusCode", statusCode);
127
234
  params.putString("message", message);
128
235
  sendEvent("onInterstitialAdShowFailed", params);
236
+ // NOTE: emit() 이후에는 Map 이 consume 되므로 재사용 금지. 새 맵으로 따로 보낸다.
237
+ WritableMap forAdEvent = Arguments.createMap();
238
+ forAdEvent.putInt("statusCode", statusCode);
239
+ forAdEvent.putString("message", message);
240
+ sendAdEvent(lastActiveAdId, "onInterstitialAdShowFailed", forAdEvent);
129
241
  }
130
242
 
131
243
  @Override
132
244
  public void onAdClosed() {
133
245
  Log.i(REACT_CLASS_NAME, "onAdClosed()");
134
246
  sendEvent("onInterstitialAdClosed", null);
247
+ sendAdEvent(lastActiveAdId, "onInterstitialAdClosed", null);
248
+
249
+ // Flutter 구현과 유사하게 닫힘 후 destroy 권장: 자동 정리(선택)
250
+ if (adsById.containsKey(lastActiveAdId)) {
251
+ destroyAd(lastActiveAdId);
252
+ }
135
253
  }
136
254
 
137
255
  @Override
138
256
  public void onAdClicked() {
139
257
  Log.i(REACT_CLASS_NAME, "onAdClicked()");
140
258
  sendEvent("onInterstitialAdClicked", null);
259
+ sendAdEvent(lastActiveAdId, "onInterstitialAdClicked", null);
141
260
  }
142
261
 
143
262
  @Nullable
@@ -153,6 +272,21 @@ public class RNAdWhaleMediationInterstitialAd extends ReactContextBaseJavaModule
153
272
  .emit(eventName, params);
154
273
  }
155
274
 
275
+ /**
276
+ * Flutter의 `onAdEvent`와 동일한 단일 이벤트 채널 형태.
277
+ * payload: { adId, eventName, ...statusCode/message... }
278
+ */
279
+ private void sendAdEvent(int adId, @NonNull String eventName, @Nullable WritableMap original) {
280
+ WritableMap payload = Arguments.createMap();
281
+ payload.putInt("adId", adId);
282
+ payload.putString("eventName", eventName);
283
+ if (original != null) {
284
+ if (original.hasKey("statusCode")) payload.putInt("statusCode", original.getInt("statusCode"));
285
+ if (original.hasKey("message")) payload.putString("message", original.getString("message"));
286
+ }
287
+ sendEvent("onAdEvent", payload);
288
+ }
289
+
156
290
  @ReactMethod
157
291
  public void addListener(String eventName) {
158
292
  //TODO NOTHING
@@ -162,4 +296,75 @@ public class RNAdWhaleMediationInterstitialAd extends ReactContextBaseJavaModule
162
296
  public void removeListeners(Integer count) {
163
297
  //TODO NOTHING
164
298
  }
299
+
300
+ /**
301
+ * adId별 전면 인스턴스 전용 리스너. 여러 개를 동시에 로드할 때 공유 리스너 + lastActiveAdId 만으로는
302
+ * 콜백이 모두 마지막 id로만 전달되는 문제가 있다.
303
+ */
304
+ private final class PerAdInterstitialListener implements AdWhaleMediationInterstitialAdListener {
305
+ private final int boundAdId;
306
+
307
+ PerAdInterstitialListener(int boundAdId) {
308
+ this.boundAdId = boundAdId;
309
+ }
310
+
311
+ @Override
312
+ public void onAdLoaded() {
313
+ Log.i(REACT_CLASS_NAME, "onAdLoaded() adId=" + boundAdId);
314
+ sendEvent("onInterstitialAdLoaded", null);
315
+ sendAdEvent(boundAdId, "onInterstitialAdLoaded", null);
316
+ }
317
+
318
+ @Override
319
+ public void onAdLoadFailed(int statusCode, String message) {
320
+ Log.i(REACT_CLASS_NAME, "onAdLoadFailed(" + statusCode + ", " + message + ") adId=" + boundAdId);
321
+ WritableMap params = Arguments.createMap();
322
+ params.putInt("statusCode", statusCode);
323
+ params.putString("message", message);
324
+ sendEvent("onInterstitialAdLoadFailed", params);
325
+ // NOTE: emit() 이후에는 Map 이 consume 되므로 재사용 금지. 새 맵으로 따로 보낸다.
326
+ WritableMap forAdEvent = Arguments.createMap();
327
+ forAdEvent.putInt("statusCode", statusCode);
328
+ forAdEvent.putString("message", message);
329
+ sendAdEvent(boundAdId, "onInterstitialAdLoadFailed", forAdEvent);
330
+ }
331
+
332
+ @Override
333
+ public void onAdShowed() {
334
+ Log.i(REACT_CLASS_NAME, "onAdShowed() adId=" + boundAdId);
335
+ sendEvent("onInterstitialAdShowed", null);
336
+ sendAdEvent(boundAdId, "onInterstitialAdShowed", null);
337
+ }
338
+
339
+ @Override
340
+ public void onAdShowFailed(int statusCode, String message) {
341
+ Log.i(REACT_CLASS_NAME, "onAdShowFailed(" + statusCode + ", " + message + ") adId=" + boundAdId);
342
+ WritableMap params = Arguments.createMap();
343
+ params.putInt("statusCode", statusCode);
344
+ params.putString("message", message);
345
+ sendEvent("onInterstitialAdShowFailed", params);
346
+ // NOTE: emit() 이후에는 Map 이 consume 되므로 재사용 금지. 새 맵으로 따로 보낸다.
347
+ WritableMap forAdEvent = Arguments.createMap();
348
+ forAdEvent.putInt("statusCode", statusCode);
349
+ forAdEvent.putString("message", message);
350
+ sendAdEvent(boundAdId, "onInterstitialAdShowFailed", forAdEvent);
351
+ }
352
+
353
+ @Override
354
+ public void onAdClosed() {
355
+ Log.i(REACT_CLASS_NAME, "onAdClosed() adId=" + boundAdId);
356
+ sendEvent("onInterstitialAdClosed", null);
357
+ sendAdEvent(boundAdId, "onInterstitialAdClosed", null);
358
+ if (adsById.containsKey(boundAdId)) {
359
+ destroyAd(boundAdId);
360
+ }
361
+ }
362
+
363
+ @Override
364
+ public void onAdClicked() {
365
+ Log.i(REACT_CLASS_NAME, "onAdClicked() adId=" + boundAdId);
366
+ sendEvent("onInterstitialAdClicked", null);
367
+ sendAdEvent(boundAdId, "onInterstitialAdClicked", null);
368
+ }
369
+ }
165
370
  }
@@ -4,6 +4,7 @@ import android.util.Log;
4
4
 
5
5
  import androidx.annotation.NonNull;
6
6
 
7
+ import com.adwhalesdkreactnative.common.RNMethodResultConst;
7
8
  import com.facebook.react.bridge.ReactApplicationContext;
8
9
  import com.facebook.react.bridge.ReactContextBaseJavaModule;
9
10
  import com.facebook.react.bridge.ReactMethod;
@@ -43,7 +44,7 @@ public class RNAdWhaleMediationLoggerModule extends ReactContextBaseJavaModule {
43
44
  promise.resolve(logLevelString);
44
45
  } catch (Exception e) {
45
46
  Log.e(REACT_CLASS_NAME, "로그 레벨 조회 실패", e);
46
- promise.reject("GET_LOG_LEVEL_ERROR", "Failed to get log level", e);
47
+ promise.reject(RNMethodResultConst.GET_LOG_LEVEL_ERROR, "Failed to get log level", e);
47
48
  }
48
49
  }
49
50
  }
@@ -0,0 +1,83 @@
1
+ package com.adwhalesdkreactnative;
2
+
3
+ import android.util.Log;
4
+
5
+ import androidx.annotation.NonNull;
6
+ import androidx.annotation.Nullable;
7
+
8
+ import com.adwhalesdkreactnative.common.RNMethodArgConst;
9
+ import com.adwhalesdkreactnative.common.RNMethodCallConst;
10
+ import com.facebook.react.bridge.Arguments;
11
+ import com.facebook.react.bridge.WritableMap;
12
+
13
+ import net.adwhale.sdk.mediation.ads.AdWhaleMediationNativeAdViewListener;
14
+
15
+ /**
16
+ * {@link AdWhaleMediationNativeAdViewListener} 단일 구현체.
17
+ * Flutter {@code FlutterNativeTemplateAd} / {@code FlutterNativeBinderAd}와 동일하게
18
+ * 모든 콜백을 동일한 이벤트 이름({@link RNMethodCallConst#ON_NATIVE_AD_*})으로 정규화합니다.
19
+ */
20
+ public final class RNAdWhaleMediationNativeAdViewListenerBridge implements AdWhaleMediationNativeAdViewListener {
21
+
22
+ /** Flutter {@link net.adwhale.sdk.adwhale_sdk_flutter.nativeads.FlutterNativeBinderAd} 와 동일. */
23
+ public static final int NATIVE_BINDER_CONFIGURATION_ERROR_CODE = 300;
24
+
25
+ /**
26
+ * 네이티브 → JS 로 이벤트를 보낼 때 사용. Flutter AdWhaleAdInstanceManager 의 emit 과 대응.
27
+ */
28
+ public interface Emitter {
29
+ void emit(@NonNull String eventName, @Nullable WritableMap payload);
30
+ }
31
+
32
+ @NonNull private final String logTag;
33
+ @NonNull private final Emitter emitter;
34
+
35
+ public RNAdWhaleMediationNativeAdViewListenerBridge(
36
+ @NonNull String logTag,
37
+ @NonNull Emitter emitter) {
38
+ this.logTag = logTag;
39
+ this.emitter = emitter;
40
+ }
41
+
42
+ @NonNull
43
+ public static WritableMap createErrorPayload(int statusCode, @Nullable String message) {
44
+ WritableMap m = Arguments.createMap();
45
+ m.putInt(RNMethodArgConst.SEND_STATUS_CODE, statusCode);
46
+ m.putString(RNMethodArgConst.SEND_MESSAGE, message != null ? message : "");
47
+ return m;
48
+ }
49
+
50
+ @Override
51
+ public void onNativeAdLoaded() {
52
+ Log.d(logTag, "onNativeAdLoaded");
53
+ emitter.emit(RNMethodCallConst.ON_NATIVE_AD_LOADED, null);
54
+ }
55
+
56
+ @Override
57
+ public void onNativeAdFailedToLoad(int errorCode, String errorMessage) {
58
+ Log.d(logTag, "onNativeAdFailedToLoad: " + errorCode + ", " + errorMessage);
59
+ emitter.emit(
60
+ RNMethodCallConst.ON_NATIVE_AD_FAILED_TO_LOAD,
61
+ createErrorPayload(errorCode, errorMessage));
62
+ }
63
+
64
+ @Override
65
+ public void onNativeAdShowFailed(int errorCode, String errorMessage) {
66
+ Log.d(logTag, "onNativeAdShowFailed: " + errorCode + ", " + errorMessage);
67
+ emitter.emit(
68
+ RNMethodCallConst.ON_NATIVE_AD_SHOW_FAILED,
69
+ createErrorPayload(errorCode, errorMessage));
70
+ }
71
+
72
+ @Override
73
+ public void onNativeAdClicked() {
74
+ Log.d(logTag, "onNativeAdClicked");
75
+ emitter.emit(RNMethodCallConst.ON_NATIVE_AD_CLICKED, null);
76
+ }
77
+
78
+ @Override
79
+ public void onNativeAdClosed() {
80
+ Log.d(logTag, "onNativeAdClosed");
81
+ emitter.emit(RNMethodCallConst.ON_NATIVE_AD_CLOSED, null);
82
+ }
83
+ }