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.
- package/AdwhaleSdkReactNative.podspec +22 -0
- package/README.md +95 -91
- package/android/build.gradle +35 -1
- package/android/proguard-rules.pro +58 -0
- package/android/src/main/java/com/adwhalesdkreactnative/AdWhaleCustomNativeBinderFactory.java +18 -0
- package/android/src/main/java/com/adwhalesdkreactnative/AdwhaleSdkReactNativePackage.java +51 -6
- package/android/src/main/java/com/adwhalesdkreactnative/BinderFactory.java +9 -0
- package/android/src/main/java/com/adwhalesdkreactnative/RNAdWhaleMediationAdSettingModule.java +148 -49
- package/android/src/main/java/com/adwhalesdkreactnative/RNAdWhaleMediationAdView.java +46 -27
- package/android/src/main/java/com/adwhalesdkreactnative/RNAdWhaleMediationAppOpenAd.java +148 -0
- package/android/src/main/java/com/adwhalesdkreactnative/RNAdWhaleMediationCustomNativeAdView.java +37 -46
- package/android/src/main/java/com/adwhalesdkreactnative/RNAdWhaleMediationExitPopupAd.java +240 -0
- package/android/src/main/java/com/adwhalesdkreactnative/RNAdWhaleMediationInterstitialAd.java +205 -0
- package/android/src/main/java/com/adwhalesdkreactnative/RNAdWhaleMediationLoggerModule.java +2 -1
- package/android/src/main/java/com/adwhalesdkreactnative/RNAdWhaleMediationNativeAdViewListenerBridge.java +83 -0
- package/android/src/main/java/com/adwhalesdkreactnative/RNAdWhaleMediationRewardAd.java +341 -6
- package/android/src/main/java/com/adwhalesdkreactnative/RNAdWhaleMediationTemplateNativeAdView.java +191 -70
- package/android/src/main/java/com/adwhalesdkreactnative/RNAdWhaleMediationTransitionPopupAd.java +218 -0
- package/android/src/main/java/com/adwhalesdkreactnative/RNWrapperView.java +137 -0
- package/android/src/main/java/com/adwhalesdkreactnative/SimpleBinderFactory.java +1 -1
- package/android/src/main/java/com/adwhalesdkreactnative/common/RNMethodArgConst.java +112 -0
- package/android/src/main/java/com/adwhalesdkreactnative/common/RNMethodCallConst.java +113 -0
- package/android/src/main/java/com/adwhalesdkreactnative/common/RNMethodResultConst.java +28 -0
- package/build/generated/ios/ReactAppDependencyProvider.podspec +34 -0
- package/ios/AdWhaleNativeCustomViewFactoryRegistry.swift +56 -0
- package/ios/AdwhaleSdkReactNative.mm +96 -5
- package/ios/AdwhaleSdkReactNativeModule.swift +148 -0
- package/ios/RNAdWhaleMediationAdViewManager.m +38 -0
- package/ios/RNAdWhaleMediationAdViewManager.swift +14 -0
- package/ios/RNAdWhaleMediationAppOpenAd.m +18 -0
- package/ios/RNAdWhaleMediationAppOpenAd.swift +175 -0
- package/ios/RNAdWhaleMediationCustomNativeAdViewManager.m +22 -0
- package/ios/RNAdWhaleMediationCustomNativeAdViewManager.swift +239 -0
- package/ios/RNAdWhaleMediationInterstitialAd.m +18 -0
- package/ios/RNAdWhaleMediationInterstitialAd.swift +161 -0
- package/ios/RNAdWhaleMediationRewardAd.m +22 -0
- package/ios/RNAdWhaleMediationRewardAd.swift +206 -0
- package/ios/WhaleMediationBannerContainer.swift +182 -0
- package/lib/module/AdWhaleAdView.js +58 -3
- package/lib/module/AdWhaleAdView.js.map +1 -1
- package/lib/module/AdWhaleAppOpenAd.js +223 -25
- package/lib/module/AdWhaleAppOpenAd.js.map +1 -1
- package/lib/module/AdWhaleExitPopupAd.js +93 -0
- package/lib/module/AdWhaleExitPopupAd.js.map +1 -0
- package/lib/module/AdWhaleInterstitialAd.js +146 -22
- package/lib/module/AdWhaleInterstitialAd.js.map +1 -1
- package/lib/module/AdWhaleMediationAds.js +75 -4
- package/lib/module/AdWhaleMediationAds.js.map +1 -1
- package/lib/module/AdWhaleNativeCustomView.js +59 -8
- package/lib/module/AdWhaleNativeCustomView.js.map +1 -1
- package/lib/module/AdWhaleNativeTemplateView.js +37 -19
- package/lib/module/AdWhaleNativeTemplateView.js.map +1 -1
- package/lib/module/AdWhaleRewardAd.js +221 -24
- package/lib/module/AdWhaleRewardAd.js.map +1 -1
- package/lib/module/AdWhaleTransitionPopupAd.js +87 -0
- package/lib/module/AdWhaleTransitionPopupAd.js.map +1 -0
- package/lib/module/NativeAdwhaleSdkReactNative.js +16 -1
- package/lib/module/NativeAdwhaleSdkReactNative.js.map +1 -1
- package/lib/module/constants/AdWhaleMethodArgConst.js +53 -0
- package/lib/module/constants/AdWhaleMethodArgConst.js.map +1 -0
- package/lib/module/constants/AdWhaleMethodCallConst.js +56 -0
- package/lib/module/constants/AdWhaleMethodCallConst.js.map +1 -0
- package/lib/module/constants/AdWhaleMethodResultConst.js +16 -0
- package/lib/module/constants/AdWhaleMethodResultConst.js.map +1 -0
- package/lib/module/index.js +10 -1
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/src/AdWhaleAdView.d.ts +20 -2
- package/lib/typescript/src/AdWhaleAdView.d.ts.map +1 -1
- package/lib/typescript/src/AdWhaleAppOpenAd.d.ts +10 -0
- package/lib/typescript/src/AdWhaleAppOpenAd.d.ts.map +1 -1
- package/lib/typescript/src/AdWhaleExitPopupAd.d.ts +36 -0
- package/lib/typescript/src/AdWhaleExitPopupAd.d.ts.map +1 -0
- package/lib/typescript/src/AdWhaleInterstitialAd.d.ts +16 -0
- package/lib/typescript/src/AdWhaleInterstitialAd.d.ts.map +1 -1
- package/lib/typescript/src/AdWhaleMediationAds.d.ts +13 -5
- package/lib/typescript/src/AdWhaleMediationAds.d.ts.map +1 -1
- package/lib/typescript/src/AdWhaleNativeCustomView.d.ts +7 -4
- package/lib/typescript/src/AdWhaleNativeCustomView.d.ts.map +1 -1
- package/lib/typescript/src/AdWhaleNativeTemplateView.d.ts +20 -7
- package/lib/typescript/src/AdWhaleNativeTemplateView.d.ts.map +1 -1
- package/lib/typescript/src/AdWhaleRewardAd.d.ts +63 -6
- package/lib/typescript/src/AdWhaleRewardAd.d.ts.map +1 -1
- package/lib/typescript/src/AdWhaleTransitionPopupAd.d.ts +33 -0
- package/lib/typescript/src/AdWhaleTransitionPopupAd.d.ts.map +1 -0
- package/lib/typescript/src/NativeAdwhaleSdkReactNative.d.ts +28 -6
- package/lib/typescript/src/NativeAdwhaleSdkReactNative.d.ts.map +1 -1
- package/lib/typescript/src/constants/AdWhaleMethodArgConst.d.ts +51 -0
- package/lib/typescript/src/constants/AdWhaleMethodArgConst.d.ts.map +1 -0
- package/lib/typescript/src/constants/AdWhaleMethodCallConst.d.ts +53 -0
- package/lib/typescript/src/constants/AdWhaleMethodCallConst.d.ts.map +1 -0
- package/lib/typescript/src/constants/AdWhaleMethodResultConst.d.ts +14 -0
- package/lib/typescript/src/constants/AdWhaleMethodResultConst.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +10 -2
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/AdWhaleAdView.tsx +92 -4
- package/src/AdWhaleAppOpenAd.ts +293 -38
- package/src/AdWhaleExitPopupAd.ts +183 -0
- package/src/AdWhaleInterstitialAd.ts +206 -36
- package/src/AdWhaleMediationAds.ts +108 -4
- package/src/AdWhaleNativeCustomView.tsx +85 -23
- package/src/AdWhaleNativeTemplateView.tsx +79 -42
- package/src/AdWhaleRewardAd.ts +317 -51
- package/src/AdWhaleTransitionPopupAd.ts +171 -0
- package/src/NativeAdwhaleSdkReactNative.ts +30 -6
- package/src/constants/AdWhaleMethodArgConst.ts +50 -0
- package/src/constants/AdWhaleMethodCallConst.ts +60 -0
- package/src/constants/AdWhaleMethodResultConst.ts +13 -0
- package/src/index.ts +35 -0
package/android/src/main/java/com/adwhalesdkreactnative/RNAdWhaleMediationTemplateNativeAdView.java
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
package com.adwhalesdkreactnative;
|
|
2
2
|
|
|
3
|
+
import android.content.Context;
|
|
3
4
|
import android.os.Handler;
|
|
4
5
|
import android.os.Looper;
|
|
5
6
|
import android.util.Log;
|
|
6
7
|
import android.view.View;
|
|
8
|
+
import android.widget.FrameLayout;
|
|
7
9
|
|
|
8
10
|
import androidx.annotation.NonNull;
|
|
9
11
|
import androidx.annotation.Nullable;
|
|
10
12
|
|
|
11
|
-
import com.facebook.react.bridge.Arguments;
|
|
12
13
|
import com.facebook.react.bridge.WritableMap;
|
|
13
14
|
import com.facebook.react.common.MapBuilder;
|
|
14
15
|
import com.facebook.react.bridge.ReadableMap;
|
|
@@ -17,8 +18,10 @@ import com.facebook.react.uimanager.ThemedReactContext;
|
|
|
17
18
|
import com.facebook.react.uimanager.annotations.ReactProp;
|
|
18
19
|
import com.facebook.react.uimanager.events.RCTEventEmitter;
|
|
19
20
|
|
|
21
|
+
import com.adwhalesdkreactnative.common.RNMethodArgConst;
|
|
22
|
+
import com.adwhalesdkreactnative.common.RNMethodCallConst;
|
|
23
|
+
|
|
20
24
|
import net.adwhale.sdk.mediation.ads.AdWhaleMediationNativeAdView;
|
|
21
|
-
import net.adwhale.sdk.mediation.ads.AdWhaleMediationNativeAdViewListener;
|
|
22
25
|
import net.adwhale.sdk.mediation.ads.ADWHALE_NATIVE_TEMPLATE;
|
|
23
26
|
import net.adwhale.sdk.mediation.ads.AdWhaleMediationNativeTemplateStyle;
|
|
24
27
|
import android.graphics.Color;
|
|
@@ -37,6 +40,11 @@ public class RNAdWhaleMediationTemplateNativeAdView extends SimpleViewManager<RN
|
|
|
37
40
|
private ADWHALE_NATIVE_TEMPLATE template = ADWHALE_NATIVE_TEMPLATE.SMALL;
|
|
38
41
|
private AdWhaleMediationNativeTemplateStyle templateStyle = null;
|
|
39
42
|
private String placementName;
|
|
43
|
+
/** {@link #resetNativeAdChild} 후에도 region/gcoder를 다시 적용하기 위해 보관 */
|
|
44
|
+
@Nullable private String cachedRegion;
|
|
45
|
+
private boolean hasCachedGcoder;
|
|
46
|
+
private double cachedGcoderLt;
|
|
47
|
+
private double cachedGcoderLng;
|
|
40
48
|
|
|
41
49
|
@NonNull
|
|
42
50
|
@Override
|
|
@@ -58,42 +66,13 @@ public class RNAdWhaleMediationTemplateNativeAdView extends SimpleViewManager<RN
|
|
|
58
66
|
AdWhaleMediationNativeAdView adWhaleMediationNativeAdView = getAdWhaleMediationNativeAdView(view);
|
|
59
67
|
if (adWhaleMediationNativeAdView == null) return;
|
|
60
68
|
|
|
61
|
-
adWhaleMediationNativeAdView.setAdWhaleMediationNativeAdViewListener(
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
@Override
|
|
70
|
-
public void onNativeAdFailedToLoad(int code, String message) {
|
|
71
|
-
Log.d(REACT_CLASS, "onNativeAdFailedToLoad: " + code + ", " + message);
|
|
72
|
-
WritableMap event = Arguments.createMap();
|
|
73
|
-
event.putInt("errorCode", code);
|
|
74
|
-
event.putString("errorMessage", message);
|
|
75
|
-
dispatchEvent(reactContext, view, "onAdFailedToLoad", event);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
@Override
|
|
79
|
-
public void onNativeAdShowFailed(int code, String message) {
|
|
80
|
-
Log.d(REACT_CLASS, "onNativeAdShowFailed: " + code + ", " + message);
|
|
81
|
-
WritableMap event = Arguments.createMap();
|
|
82
|
-
event.putInt("errorCode", code);
|
|
83
|
-
event.putString("errorMessage", message);
|
|
84
|
-
dispatchEvent(reactContext, view, "onAdShowFailed", event);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
@Override
|
|
88
|
-
public void onNativeAdClicked() {
|
|
89
|
-
// Not used in RN
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
@Override
|
|
93
|
-
public void onNativeAdClosed() {
|
|
94
|
-
// Not used in RN
|
|
95
|
-
}
|
|
96
|
-
});
|
|
69
|
+
adWhaleMediationNativeAdView.setAdWhaleMediationNativeAdViewListener(
|
|
70
|
+
new RNAdWhaleMediationNativeAdViewListenerBridge(REACT_CLASS, (eventName, payload) -> {
|
|
71
|
+
dispatchEvent(reactContext, view, eventName, payload);
|
|
72
|
+
if (RNMethodCallConst.ON_NATIVE_AD_LOADED.equals(eventName)) {
|
|
73
|
+
view.requestLayout();
|
|
74
|
+
}
|
|
75
|
+
}));
|
|
97
76
|
}
|
|
98
77
|
|
|
99
78
|
private void dispatchEvent(ThemedReactContext context, View view, String eventName, @Nullable WritableMap eventData) {
|
|
@@ -108,9 +87,11 @@ public class RNAdWhaleMediationTemplateNativeAdView extends SimpleViewManager<RN
|
|
|
108
87
|
@Override
|
|
109
88
|
public Map<String, Object> getExportedCustomDirectEventTypeConstants() {
|
|
110
89
|
MapBuilder.Builder<String, Object> builder = MapBuilder.builder();
|
|
111
|
-
builder.put(
|
|
112
|
-
builder.put(
|
|
113
|
-
builder.put(
|
|
90
|
+
builder.put(RNMethodCallConst.ON_NATIVE_AD_LOADED, MapBuilder.of(RNMethodArgConst.SEND_REGISTRATION_NAME, RNMethodCallConst.ON_NATIVE_AD_LOADED));
|
|
91
|
+
builder.put(RNMethodCallConst.ON_NATIVE_AD_FAILED_TO_LOAD, MapBuilder.of(RNMethodArgConst.SEND_REGISTRATION_NAME, RNMethodCallConst.ON_NATIVE_AD_FAILED_TO_LOAD));
|
|
92
|
+
builder.put(RNMethodCallConst.ON_NATIVE_AD_SHOW_FAILED, MapBuilder.of(RNMethodArgConst.SEND_REGISTRATION_NAME, RNMethodCallConst.ON_NATIVE_AD_SHOW_FAILED));
|
|
93
|
+
builder.put(RNMethodCallConst.ON_NATIVE_AD_CLICKED, MapBuilder.of(RNMethodArgConst.SEND_REGISTRATION_NAME, RNMethodCallConst.ON_NATIVE_AD_CLICKED));
|
|
94
|
+
builder.put(RNMethodCallConst.ON_NATIVE_AD_CLOSED, MapBuilder.of(RNMethodArgConst.SEND_REGISTRATION_NAME, RNMethodCallConst.ON_NATIVE_AD_CLOSED));
|
|
114
95
|
return builder.build();
|
|
115
96
|
}
|
|
116
97
|
|
|
@@ -123,6 +104,7 @@ public class RNAdWhaleMediationTemplateNativeAdView extends SimpleViewManager<RN
|
|
|
123
104
|
@ReactProp(name = "region")
|
|
124
105
|
public void setRegion(RNWrapperView view, String region) {
|
|
125
106
|
Log.e(REACT_CLASS, "region: " + region);
|
|
107
|
+
this.cachedRegion = region;
|
|
126
108
|
AdWhaleMediationNativeAdView adView = getAdWhaleMediationNativeAdView(view);
|
|
127
109
|
if (adView != null) {
|
|
128
110
|
adView.setRegion(region);
|
|
@@ -134,11 +116,17 @@ public class RNAdWhaleMediationTemplateNativeAdView extends SimpleViewManager<RN
|
|
|
134
116
|
Log.e(REACT_CLASS, "gcoderMap: " + gcoderMap);
|
|
135
117
|
AdWhaleMediationNativeAdView adView = getAdWhaleMediationNativeAdView(view);
|
|
136
118
|
|
|
137
|
-
if (
|
|
119
|
+
if (gcoderMap != null) {
|
|
138
120
|
double lt = gcoderMap.hasKey("lt") ? gcoderMap.getDouble("lt") : 0.0;
|
|
139
121
|
double lng = gcoderMap.hasKey("lng") ? gcoderMap.getDouble("lng") : 0.0;
|
|
140
|
-
|
|
141
|
-
|
|
122
|
+
this.hasCachedGcoder = true;
|
|
123
|
+
this.cachedGcoderLt = lt;
|
|
124
|
+
this.cachedGcoderLng = lng;
|
|
125
|
+
if (adView != null) {
|
|
126
|
+
adView.setGcoder(lt, lng);
|
|
127
|
+
}
|
|
128
|
+
} else {
|
|
129
|
+
this.hasCachedGcoder = false;
|
|
142
130
|
}
|
|
143
131
|
}
|
|
144
132
|
|
|
@@ -278,11 +266,82 @@ public class RNAdWhaleMediationTemplateNativeAdView extends SimpleViewManager<RN
|
|
|
278
266
|
|
|
279
267
|
@ReactProp(name = "placementUid")
|
|
280
268
|
public void setPlacementUid(RNWrapperView view, String placementUid) {
|
|
281
|
-
|
|
269
|
+
String u = placementUid != null ? placementUid : "";
|
|
270
|
+
this.placementUid = u;
|
|
271
|
+
view.setStoredPlacementUid(u);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Fabric(New Arch)에서는 {@code findNodeHandle + dispatchViewManagerCommand}가
|
|
276
|
+
* shadow node 미준비 시 조용히 무시될 수 있어, prop 기반 트리거를 함께 둡니다.
|
|
277
|
+
* JS는 값이 바뀔 때마다 1씩 올립니다(0은 무시).
|
|
278
|
+
*/
|
|
279
|
+
@ReactProp(name = "viewSyncKey", defaultInt = -1)
|
|
280
|
+
public void setViewSyncKey(RNWrapperView view, int viewSyncKey) {
|
|
281
|
+
int prev = view.getViewSyncKey();
|
|
282
|
+
if (viewSyncKey != -1 && prev != -1 && prev != viewSyncKey) {
|
|
283
|
+
view.resetRequestDedupeState();
|
|
284
|
+
view.setViewSyncKey(viewSyncKey);
|
|
285
|
+
view.setLastConsumedLoadRequestId(0);
|
|
286
|
+
view.setLastConsumedShowRequestId(0);
|
|
287
|
+
Log.d(REACT_CLASS, "viewSyncKey " + prev + " -> " + viewSyncKey + " (reset load/show dedupe)");
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
if (viewSyncKey != -1) {
|
|
291
|
+
view.setViewSyncKey(viewSyncKey);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
@ReactProp(name = "loadRequestId")
|
|
296
|
+
public void setLoadRequestId(RNWrapperView view, int loadRequestId) {
|
|
297
|
+
Log.d(REACT_CLASS, "setLoadRequestId(view=" + view.getId() + ", sync=" + view.getViewSyncKey() + ", id=" + loadRequestId + ")");
|
|
298
|
+
if (loadRequestId <= 0) {
|
|
299
|
+
// JS가 시그널을 0으로 리셋할 때마다 소비 카운터를 비움. Fabric이 네이티브 래퍼를 재사용하면
|
|
300
|
+
// 이전 reactTag에서 lastConsumed=1이 남아 동일 id=1 로드가 영구 스킵되는 문제를 막음.
|
|
301
|
+
view.setLastConsumedLoadRequestId(0);
|
|
302
|
+
view.clearLoadRequestDedupePair();
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
// 동일 (viewSyncKey, loadRequestId) 조합만 스킵 — 템플릿 전환 후 다시 id=1이 와도 syncKey가 바뀌면 처리됨
|
|
306
|
+
if (view.shouldSkipLoadRequestDedupe(loadRequestId)) {
|
|
307
|
+
Log.d(REACT_CLASS, "setLoadRequestId skip duplicate (sync=" + view.getViewSyncKey() + ", id=" + loadRequestId + ")");
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
view.markLoadRequestDeduped(loadRequestId);
|
|
311
|
+
view.setLastConsumedLoadRequestId(loadRequestId);
|
|
312
|
+
Log.d(REACT_CLASS, "loadRequestId prop -> schedule loadAd (id=" + loadRequestId + ")");
|
|
313
|
+
// 동일 레이아웃 패스에서 다른 @ReactProp(placementUid, template 등)이 아직 안 올 수 있음
|
|
314
|
+
view.post(() -> loadAd(view));
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
@ReactProp(name = "showRequestId")
|
|
318
|
+
public void setShowRequestId(RNWrapperView view, int showRequestId) {
|
|
319
|
+
Log.d(REACT_CLASS, "setShowRequestId(view=" + view.getId() + ", sync=" + view.getViewSyncKey() + ", id=" + showRequestId + ")");
|
|
320
|
+
if (showRequestId <= 0) {
|
|
321
|
+
view.setLastConsumedShowRequestId(0);
|
|
322
|
+
view.clearShowRequestDedupePair();
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
if (view.shouldSkipShowRequestDedupe(showRequestId)) {
|
|
326
|
+
Log.d(REACT_CLASS, "setShowRequestId skip duplicate (sync=" + view.getViewSyncKey() + ", id=" + showRequestId + ")");
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
view.markShowRequestDeduped(showRequestId);
|
|
330
|
+
view.setLastConsumedShowRequestId(showRequestId);
|
|
331
|
+
Log.d(REACT_CLASS, "showRequestId prop -> schedule showAd (id=" + showRequestId + ")");
|
|
332
|
+
view.post(() -> showAd(view));
|
|
282
333
|
}
|
|
283
334
|
|
|
284
335
|
@ReactProp(name = "template")
|
|
285
336
|
public void setTemplate(RNWrapperView view, String templateName) {
|
|
337
|
+
if (templateName != null) {
|
|
338
|
+
String prev = view.getLastReactTemplateKey();
|
|
339
|
+
if (prev != null && !prev.equalsIgnoreCase(templateName)) {
|
|
340
|
+
view.setRecreateNativeAdChildBeforeNextLoad(true);
|
|
341
|
+
}
|
|
342
|
+
view.setLastReactTemplateKey(templateName);
|
|
343
|
+
view.setStoredTemplateKey(templateName);
|
|
344
|
+
}
|
|
286
345
|
if ("SMALL".equalsIgnoreCase(templateName)) {
|
|
287
346
|
this.template = ADWHALE_NATIVE_TEMPLATE.SMALL;
|
|
288
347
|
} else if ("MEDIUM".equalsIgnoreCase(templateName)) {
|
|
@@ -292,45 +351,107 @@ public class RNAdWhaleMediationTemplateNativeAdView extends SimpleViewManager<RN
|
|
|
292
351
|
}
|
|
293
352
|
}
|
|
294
353
|
|
|
354
|
+
private static ADWHALE_NATIVE_TEMPLATE parseTemplateKey(@Nullable String templateName) {
|
|
355
|
+
if ("MEDIUM".equalsIgnoreCase(templateName)) {
|
|
356
|
+
return ADWHALE_NATIVE_TEMPLATE.MEDIUM;
|
|
357
|
+
}
|
|
358
|
+
if ("FULLSCREEN".equalsIgnoreCase(templateName)) {
|
|
359
|
+
return ADWHALE_NATIVE_TEMPLATE.FULLSCREEN;
|
|
360
|
+
}
|
|
361
|
+
return ADWHALE_NATIVE_TEMPLATE.SMALL;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* 템플릿 전환·재로드·show() 이후 동일 뷰에서 다시 로드할 때 SDK가 콜백을 주지 않는 경우가 있어
|
|
366
|
+
* {@link AdWhaleMediationNativeAdView}를 새로 붙이고 리스너를 다시 연결합니다.
|
|
367
|
+
*/
|
|
368
|
+
private void resetNativeAdChild(@NonNull RNWrapperView wrapper) {
|
|
369
|
+
Context ctx = wrapper.getContext();
|
|
370
|
+
if (!(ctx instanceof ThemedReactContext)) {
|
|
371
|
+
Log.e(REACT_CLASS, "resetNativeAdChild: context is not ThemedReactContext");
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
ThemedReactContext themedContext = (ThemedReactContext) ctx;
|
|
375
|
+
AdWhaleMediationNativeAdView old = getAdWhaleMediationNativeAdView(wrapper);
|
|
376
|
+
if (old != null) {
|
|
377
|
+
try {
|
|
378
|
+
old.destroy();
|
|
379
|
+
} catch (Throwable t) {
|
|
380
|
+
Log.w(REACT_CLASS, "destroy before reload failed: " + t.getMessage());
|
|
381
|
+
}
|
|
382
|
+
wrapper.removeView(old);
|
|
383
|
+
}
|
|
384
|
+
AdWhaleMediationNativeAdView fresh = new AdWhaleMediationNativeAdView(themedContext);
|
|
385
|
+
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
|
|
386
|
+
FrameLayout.LayoutParams.MATCH_PARENT,
|
|
387
|
+
FrameLayout.LayoutParams.WRAP_CONTENT);
|
|
388
|
+
wrapper.addView(fresh, 0, lp);
|
|
389
|
+
setAdListener(themedContext, wrapper);
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
private void applyCachedOptions(@NonNull AdWhaleMediationNativeAdView adView) {
|
|
393
|
+
if (cachedRegion != null) {
|
|
394
|
+
adView.setRegion(cachedRegion);
|
|
395
|
+
}
|
|
396
|
+
if (hasCachedGcoder) {
|
|
397
|
+
adView.setGcoder(cachedGcoderLt, cachedGcoderLng);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
|
|
295
401
|
private void loadAd(RNWrapperView view) {
|
|
296
402
|
new Handler(Looper.getMainLooper()).post(() -> {
|
|
403
|
+
final String uid = view.getStoredPlacementUid();
|
|
404
|
+
final ADWHALE_NATIVE_TEMPLATE tmpl = parseTemplateKey(view.getStoredTemplateKey());
|
|
405
|
+
if (uid.isEmpty()) {
|
|
406
|
+
Log.e(REACT_CLASS, "Placement UID is empty on view. Cannot load ad.");
|
|
407
|
+
return;
|
|
408
|
+
}
|
|
409
|
+
// 매 로드마다 자식을 갈아끼우면, remount 직후 첫 로드에서 방금 만든 뷰가 깨지거나 SDK가 응답하지 않는 경우가 있음.
|
|
410
|
+
// show() 이후 재로드, 또는 동일 래퍼에서 template prop만 바뀐 경우에만 재생성.
|
|
411
|
+
if (view.isRecreateNativeAdChildBeforeNextLoad()) {
|
|
412
|
+
Log.d(REACT_CLASS, "Recreating native ad child before load (template change or post-show).");
|
|
413
|
+
resetNativeAdChild(view);
|
|
414
|
+
view.setRecreateNativeAdChildBeforeNextLoad(false);
|
|
415
|
+
}
|
|
297
416
|
AdWhaleMediationNativeAdView adWhaleMediationNativeAdView = getAdWhaleMediationNativeAdView(view);
|
|
298
|
-
if (adWhaleMediationNativeAdView
|
|
299
|
-
if (placementUid == null || placementUid.isEmpty()) {
|
|
300
|
-
Log.e(REACT_CLASS, "Placement UID is null or empty. Cannot load ad.");
|
|
301
|
-
return;
|
|
302
|
-
}
|
|
303
|
-
if (template == null) {
|
|
304
|
-
Log.e(REACT_CLASS, "Template is null. Cannot load ad.");
|
|
305
|
-
return;
|
|
306
|
-
}
|
|
307
|
-
Log.d(REACT_CLASS, "Placement UID: " + placementUid);
|
|
308
|
-
Log.d(REACT_CLASS, "Template: " + template.name());
|
|
309
|
-
adWhaleMediationNativeAdView.setPlacementUid(placementUid);
|
|
310
|
-
if (this.templateStyle != null) {
|
|
311
|
-
adWhaleMediationNativeAdView.setTemplateStyle(this.templateStyle);
|
|
312
|
-
}
|
|
313
|
-
adWhaleMediationNativeAdView.loadAdWithTemplate(template);
|
|
314
|
-
Log.d(REACT_CLASS, "Calling loadAdWithTemplate...");
|
|
315
|
-
} else {
|
|
417
|
+
if (adWhaleMediationNativeAdView == null) {
|
|
316
418
|
Log.e(REACT_CLASS, "adWhaleMediationNativeAdView is null. Cannot load ad.");
|
|
419
|
+
return;
|
|
317
420
|
}
|
|
421
|
+
Log.d(REACT_CLASS, "Placement UID: " + uid + " (view template key=" + view.getStoredTemplateKey() + ")");
|
|
422
|
+
Log.d(REACT_CLASS, "Template: " + tmpl.name());
|
|
423
|
+
applyCachedOptions(adWhaleMediationNativeAdView);
|
|
424
|
+
adWhaleMediationNativeAdView.setPlacementUid(uid);
|
|
425
|
+
if (this.templateStyle != null) {
|
|
426
|
+
adWhaleMediationNativeAdView.setTemplateStyle(this.templateStyle);
|
|
427
|
+
}
|
|
428
|
+
adWhaleMediationNativeAdView.loadAdWithTemplate(tmpl);
|
|
429
|
+
Log.d(REACT_CLASS, "Calling loadAdWithTemplate...");
|
|
430
|
+
view.requestLayout();
|
|
318
431
|
});
|
|
319
432
|
}
|
|
320
433
|
|
|
321
434
|
private void showAd(RNWrapperView view) {
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
adWhaleMediationNativeAdView
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
435
|
+
new Handler(Looper.getMainLooper()).post(() -> {
|
|
436
|
+
AdWhaleMediationNativeAdView adWhaleMediationNativeAdView = getAdWhaleMediationNativeAdView(view);
|
|
437
|
+
if (adWhaleMediationNativeAdView != null) {
|
|
438
|
+
adWhaleMediationNativeAdView.show();
|
|
439
|
+
view.setRecreateNativeAdChildBeforeNextLoad(true);
|
|
440
|
+
} else {
|
|
441
|
+
Log.e(REACT_CLASS, "adWhaleMediationNativeAdView is null. Cannot show ad.");
|
|
442
|
+
}
|
|
443
|
+
});
|
|
328
444
|
}
|
|
329
445
|
|
|
330
446
|
@Override
|
|
331
447
|
public void onDropViewInstance(@NonNull RNWrapperView view) {
|
|
332
448
|
super.onDropViewInstance(view);
|
|
333
|
-
Log.d(REACT_CLASS, "onDropViewInstance
|
|
449
|
+
Log.d(REACT_CLASS, "onDropViewInstance reactTag=" + view.getId());
|
|
450
|
+
view.setLastConsumedLoadRequestId(0);
|
|
451
|
+
view.setLastConsumedShowRequestId(0);
|
|
452
|
+
view.resetRequestDedupeState();
|
|
453
|
+
view.setRecreateNativeAdChildBeforeNextLoad(false);
|
|
454
|
+
view.setLastReactTemplateKey(null);
|
|
334
455
|
AdWhaleMediationNativeAdView adWhaleMediationNativeAdView = getAdWhaleMediationNativeAdView(view);
|
|
335
456
|
if (adWhaleMediationNativeAdView != null) {
|
|
336
457
|
adWhaleMediationNativeAdView.destroy();
|
package/android/src/main/java/com/adwhalesdkreactnative/RNAdWhaleMediationTransitionPopupAd.java
ADDED
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
package com.adwhalesdkreactnative;
|
|
2
|
+
|
|
3
|
+
import android.app.Activity;
|
|
4
|
+
import android.util.Log;
|
|
5
|
+
|
|
6
|
+
import androidx.annotation.NonNull;
|
|
7
|
+
import androidx.annotation.Nullable;
|
|
8
|
+
import androidx.fragment.app.FragmentActivity;
|
|
9
|
+
import androidx.fragment.app.FragmentManager;
|
|
10
|
+
|
|
11
|
+
import com.facebook.react.bridge.Arguments;
|
|
12
|
+
import com.facebook.react.bridge.ReactApplicationContext;
|
|
13
|
+
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
|
14
|
+
import com.facebook.react.bridge.ReactMethod;
|
|
15
|
+
import com.facebook.react.bridge.ReadableMap;
|
|
16
|
+
import com.facebook.react.bridge.UiThreadUtil;
|
|
17
|
+
import com.facebook.react.bridge.WritableMap;
|
|
18
|
+
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
|
19
|
+
|
|
20
|
+
import net.adwhale.sdk.mediation.ads.ADWHALE_POPUP_AD_CLOSE_REASON;
|
|
21
|
+
import net.adwhale.sdk.mediation.ads.AdWhaleMediationTransitionPopupAd;
|
|
22
|
+
import net.adwhale.sdk.mediation.ads.AdWhaleMediationTransitionPopupAdListener;
|
|
23
|
+
import net.adwhale.sdk.utils.AdWhaleLog;
|
|
24
|
+
|
|
25
|
+
import java.util.HashMap;
|
|
26
|
+
import java.util.Map;
|
|
27
|
+
|
|
28
|
+
public class RNAdWhaleMediationTransitionPopupAd extends ReactContextBaseJavaModule implements AdWhaleMediationTransitionPopupAdListener {
|
|
29
|
+
|
|
30
|
+
public static final String REACT_CLASS_NAME = RNAdWhaleMediationTransitionPopupAd.class.getSimpleName();
|
|
31
|
+
private AdWhaleMediationTransitionPopupAd adWhaleMediationTransitionPopupAd;
|
|
32
|
+
private ReactApplicationContext reactContext;
|
|
33
|
+
private String placementUid;
|
|
34
|
+
private String placementName;
|
|
35
|
+
private String region;
|
|
36
|
+
private double lt;
|
|
37
|
+
private double lng;
|
|
38
|
+
|
|
39
|
+
public RNAdWhaleMediationTransitionPopupAd(ReactApplicationContext context) {
|
|
40
|
+
super(context);
|
|
41
|
+
reactContext = context;
|
|
42
|
+
}
|
|
43
|
+
@NonNull
|
|
44
|
+
@Override
|
|
45
|
+
public String getName() {
|
|
46
|
+
return REACT_CLASS_NAME;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
@ReactMethod
|
|
50
|
+
public void setPlacementName(String placementName) {
|
|
51
|
+
Log.d(REACT_CLASS_NAME, "placementName: " + placementName);
|
|
52
|
+
this.placementName = placementName;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
@ReactMethod
|
|
56
|
+
public void setRegion(String region) {
|
|
57
|
+
Log.d(REACT_CLASS_NAME, "region: " + region);
|
|
58
|
+
this.region = region;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
@ReactMethod
|
|
62
|
+
public void setGcoder(ReadableMap gcoderMap) {
|
|
63
|
+
Log.d(REACT_CLASS_NAME, "gcoderMap: " + gcoderMap);
|
|
64
|
+
|
|
65
|
+
if (gcoderMap != null) {
|
|
66
|
+
double lt = gcoderMap.hasKey("lt") ? gcoderMap.getDouble("lt") : 0.0;
|
|
67
|
+
double lng = gcoderMap.hasKey("lng") ? gcoderMap.getDouble("lng") : 0.0;
|
|
68
|
+
|
|
69
|
+
this.lt = lt;
|
|
70
|
+
this.lng = lng;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
@ReactMethod
|
|
75
|
+
public void loadAd(String placementUid) {
|
|
76
|
+
Log.e(REACT_CLASS_NAME, ".loadAd()");
|
|
77
|
+
this.placementUid = placementUid;
|
|
78
|
+
adWhaleMediationTransitionPopupAd = new AdWhaleMediationTransitionPopupAd(placementUid);
|
|
79
|
+
adWhaleMediationTransitionPopupAd.setAdWhaleMediationTransitionPopupAdListener(this);
|
|
80
|
+
adWhaleMediationTransitionPopupAd.setPlacementName(placementName);
|
|
81
|
+
adWhaleMediationTransitionPopupAd.setRegion(region);
|
|
82
|
+
adWhaleMediationTransitionPopupAd.setGcoder(lt, lng);
|
|
83
|
+
|
|
84
|
+
UiThreadUtil.runOnUiThread(() -> {
|
|
85
|
+
adWhaleMediationTransitionPopupAd.loadAd();
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
@ReactMethod
|
|
90
|
+
public void showAd() {
|
|
91
|
+
if (adWhaleMediationTransitionPopupAd == null) {
|
|
92
|
+
AdWhaleLog.d(REACT_CLASS_NAME +" Error showing transition popup - the transition popup ad wasn't loaded yet.");
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
UiThreadUtil.runOnUiThread(() -> {
|
|
97
|
+
Activity activity = reactContext.getCurrentActivity();
|
|
98
|
+
if (activity == null) {
|
|
99
|
+
AdWhaleLog.d(REACT_CLASS_NAME + " Tried to show transition popup before activity was bound to the plugin.");
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
try {
|
|
104
|
+
if (!(activity instanceof FragmentActivity)) {
|
|
105
|
+
AdWhaleLog.d(REACT_CLASS_NAME + " Activity must be FragmentActivity to show TransitionPopupAd.");
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
FragmentManager fragmentManager =
|
|
110
|
+
((FragmentActivity) activity).getSupportFragmentManager();
|
|
111
|
+
adWhaleMediationTransitionPopupAd.showAd(activity, fragmentManager);
|
|
112
|
+
} catch (Throwable t) {
|
|
113
|
+
AdWhaleLog.d(REACT_CLASS_NAME +".showAd() failed. " + t.getMessage());
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
@ReactMethod
|
|
119
|
+
public void destroy() {
|
|
120
|
+
try {
|
|
121
|
+
if (adWhaleMediationTransitionPopupAd != null) {
|
|
122
|
+
adWhaleMediationTransitionPopupAd.destroy();
|
|
123
|
+
}
|
|
124
|
+
} catch (Throwable t) {
|
|
125
|
+
AdWhaleLog.d(REACT_CLASS_NAME +".destroy() failed. " + t.getMessage());
|
|
126
|
+
} finally {
|
|
127
|
+
adWhaleMediationTransitionPopupAd = null;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
@ReactMethod
|
|
132
|
+
public void resume() {
|
|
133
|
+
Activity activity = reactContext.getCurrentActivity();
|
|
134
|
+
if (activity == null) {
|
|
135
|
+
AdWhaleLog.d(REACT_CLASS_NAME + " Tried to resume transition popup before activity was bound to the plugin.");
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
try {
|
|
140
|
+
if (adWhaleMediationTransitionPopupAd != null) {
|
|
141
|
+
adWhaleMediationTransitionPopupAd.resume(activity);
|
|
142
|
+
}
|
|
143
|
+
} catch (Throwable t) {
|
|
144
|
+
AdWhaleLog.d(REACT_CLASS_NAME +".resume() failed. " + t.getMessage());
|
|
145
|
+
} finally {
|
|
146
|
+
adWhaleMediationTransitionPopupAd = null;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
@Override
|
|
151
|
+
public void onAdLoaded() {
|
|
152
|
+
Log.i(REACT_CLASS_NAME, "onAdLoaded()");
|
|
153
|
+
sendEvent("onTransitionPopupAdLoaded", null);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
@Override
|
|
157
|
+
public void onAdLoadFailed(int statusCode, String message) {
|
|
158
|
+
Log.i(REACT_CLASS_NAME, "onAdLoadFailed(" + statusCode + ", " + message + ")");
|
|
159
|
+
WritableMap params = Arguments.createMap();
|
|
160
|
+
params.putInt("statusCode", statusCode);
|
|
161
|
+
params.putString("message", message);
|
|
162
|
+
sendEvent("onTransitionPopupAdLoadFailed", params);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
@Override
|
|
166
|
+
public void onAdShowed() {
|
|
167
|
+
Log.i(REACT_CLASS_NAME, "onAdShowed()");
|
|
168
|
+
sendEvent("onTransitionPopupAdShowed", null);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
@Override
|
|
172
|
+
public void onAdClicked() {
|
|
173
|
+
Log.i(REACT_CLASS_NAME, "onAdClicked()");
|
|
174
|
+
sendEvent("onTransitionPopupAdClicked", null);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
@Override
|
|
178
|
+
public void onAdShowFailed(int statusCode, String message) {
|
|
179
|
+
Log.i(REACT_CLASS_NAME, "onAdShowFailed(" + statusCode + ", " + message + ")");
|
|
180
|
+
WritableMap params = Arguments.createMap();
|
|
181
|
+
params.putInt("statusCode", statusCode);
|
|
182
|
+
params.putString("message", message);
|
|
183
|
+
sendEvent("onTransitionPopupAdShowFailed", params);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
@Override
|
|
187
|
+
public void onAdClosed(ADWHALE_POPUP_AD_CLOSE_REASON adwhalePopupAdCloseReason) {
|
|
188
|
+
Log.i(REACT_CLASS_NAME, "onAdClosed()");
|
|
189
|
+
WritableMap params = Arguments.createMap();
|
|
190
|
+
params.putInt("reasonId", adwhalePopupAdCloseReason.getIdx());
|
|
191
|
+
params.putString("reasonMessage", adwhalePopupAdCloseReason.getCloseReasonTypeString());
|
|
192
|
+
sendEvent("onTransitionPopupAdClosed", params);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
@Nullable
|
|
196
|
+
@Override
|
|
197
|
+
public Map<String, Object> getConstants() {
|
|
198
|
+
final Map<String, Object> constants = new HashMap<>();
|
|
199
|
+
return constants;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
private void sendEvent(String eventName, @Nullable WritableMap params) {
|
|
203
|
+
getReactApplicationContext()
|
|
204
|
+
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
|
|
205
|
+
.emit(eventName, params);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
@ReactMethod
|
|
209
|
+
public void addListener(String eventName) {
|
|
210
|
+
// NativeEventEmitter 요구사항 (이벤트는 RCTDeviceEventEmitter로 전달)
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
@ReactMethod
|
|
214
|
+
public void removeListeners(Integer count) {
|
|
215
|
+
// NativeEventEmitter 요구사항
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
}
|