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
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
// src/AdWhaleNativeTemplateView.tsx
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
2
|
+
import { forwardRef, useImperativeHandle, useState } from 'react';
|
|
3
|
+
import { Platform, requireNativeComponent } from 'react-native';
|
|
4
4
|
import type {
|
|
5
5
|
NativeSyntheticEvent,
|
|
6
6
|
StyleProp,
|
|
7
|
+
ViewProps,
|
|
7
8
|
ViewStyle,
|
|
8
9
|
} from 'react-native';
|
|
9
10
|
|
|
@@ -29,8 +30,8 @@ export interface AdWhaleNativeTemplateStyle {
|
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
export interface AdWhaleNativeTemplateError {
|
|
32
|
-
|
|
33
|
-
|
|
33
|
+
statusCode: number;
|
|
34
|
+
message: string;
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
export interface AdWhaleNativeTemplateGcoder {
|
|
@@ -47,9 +48,24 @@ export interface AdWhaleNativeTemplateViewProps {
|
|
|
47
48
|
template: AdWhaleNativeTemplateType;
|
|
48
49
|
templateStyle?: AdWhaleNativeTemplateStyle;
|
|
49
50
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
/**
|
|
52
|
+
* Android Fabric: `ref.loadAd()` 대신 부모 state로 증가시키는 방식(권장).
|
|
53
|
+
* 지정 시 0은 무시, 1 이상이 바뀔 때마다 네이티브 load. 타입 전환 시 0으로 리셋 후 증가.
|
|
54
|
+
*/
|
|
55
|
+
loadSignal?: number;
|
|
56
|
+
/** {@link loadSignal}과 동일하게 표시 트리거 */
|
|
57
|
+
showSignal?: number;
|
|
58
|
+
/**
|
|
59
|
+
* 템플릿/스타일 전환 시마다 바꿔 주는 논리 인스턴스 키(예: `adViewKey`).
|
|
60
|
+
* `loadSignal`이 다시 1이 되어도 네이티브가 이전 인스턴스와 동일 요청으로 오인해 스킵하지 않게 합니다.
|
|
61
|
+
*/
|
|
62
|
+
viewSyncKey?: number;
|
|
63
|
+
|
|
64
|
+
onNativeAdLoaded?: () => void;
|
|
65
|
+
onNativeAdFailedToLoad?: (event: AdWhaleNativeTemplateError) => void;
|
|
66
|
+
onNativeAdShowFailed?: (event: AdWhaleNativeTemplateError) => void;
|
|
67
|
+
onNativeAdClicked?: () => void;
|
|
68
|
+
onNativeAdClosed?: () => void;
|
|
53
69
|
}
|
|
54
70
|
|
|
55
71
|
export interface AdWhaleNativeTemplateHandle {
|
|
@@ -62,10 +78,19 @@ type NativeErrorEvent = NativeSyntheticEvent<AdWhaleNativeTemplateError>;
|
|
|
62
78
|
interface NativeProps
|
|
63
79
|
extends Omit<
|
|
64
80
|
AdWhaleNativeTemplateViewProps,
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
81
|
+
| 'onNativeAdFailedToLoad'
|
|
82
|
+
| 'onNativeAdShowFailed'
|
|
83
|
+
| 'loadSignal'
|
|
84
|
+
| 'showSignal'
|
|
85
|
+
| 'viewSyncKey'
|
|
86
|
+
>,
|
|
87
|
+
Pick<ViewProps, 'collapsable'> {
|
|
88
|
+
onNativeAdFailedToLoad?: (e: NativeErrorEvent) => void;
|
|
89
|
+
onNativeAdShowFailed?: (e: NativeErrorEvent) => void;
|
|
90
|
+
/** Android: Fabric에서 View 명령이 무시되는 경우를 피하기 위해 prop으로 전달 */
|
|
91
|
+
loadRequestId?: number;
|
|
92
|
+
showRequestId?: number;
|
|
93
|
+
viewSyncKey?: number;
|
|
69
94
|
}
|
|
70
95
|
|
|
71
96
|
const VIEW_MANAGER_NAME = 'RNAdWhaleMediationTemplateNativeAdView';
|
|
@@ -77,51 +102,63 @@ export const AdWhaleNativeTemplateView = forwardRef<
|
|
|
77
102
|
AdWhaleNativeTemplateHandle,
|
|
78
103
|
AdWhaleNativeTemplateViewProps
|
|
79
104
|
>((props, ref) => {
|
|
80
|
-
|
|
105
|
+
if (Platform.OS === 'ios') {
|
|
106
|
+
// iOS는 커스텀 바인딩만 지원 (템플릿 바인딩 미지원)
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
const {
|
|
110
|
+
loadSignal,
|
|
111
|
+
showSignal,
|
|
112
|
+
viewSyncKey,
|
|
113
|
+
onNativeAdFailedToLoad,
|
|
114
|
+
onNativeAdShowFailed,
|
|
115
|
+
...nativeRest
|
|
116
|
+
} = props;
|
|
117
|
+
|
|
118
|
+
const [internalLoadId, setInternalLoadId] = useState(0);
|
|
119
|
+
const [internalShowId, setInternalShowId] = useState(0);
|
|
120
|
+
|
|
121
|
+
const useExternalLoad = loadSignal !== undefined;
|
|
122
|
+
const useExternalShow = showSignal !== undefined;
|
|
123
|
+
const loadRequestIdForNative = useExternalLoad ? loadSignal : internalLoadId;
|
|
124
|
+
const showRequestIdForNative = useExternalShow ? showSignal : internalShowId;
|
|
81
125
|
|
|
82
126
|
useImperativeHandle(ref, () => ({
|
|
83
127
|
loadAd() {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
| undefined;
|
|
89
|
-
if (!config?.Commands?.loadAd) return;
|
|
90
|
-
UIManager.dispatchViewManagerCommand(
|
|
91
|
-
handle,
|
|
92
|
-
config.Commands.loadAd,
|
|
93
|
-
[],
|
|
94
|
-
);
|
|
128
|
+
if (useExternalLoad) {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
setInternalLoadId(v => v + 1);
|
|
95
132
|
},
|
|
96
133
|
showAd() {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
| undefined;
|
|
102
|
-
if (!config?.Commands?.showAd) return;
|
|
103
|
-
UIManager.dispatchViewManagerCommand(
|
|
104
|
-
handle,
|
|
105
|
-
config.Commands.showAd,
|
|
106
|
-
[],
|
|
107
|
-
);
|
|
134
|
+
if (useExternalShow) {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
setInternalShowId(v => v + 1);
|
|
108
138
|
},
|
|
109
139
|
}));
|
|
110
140
|
|
|
111
|
-
const handleFailedToLoad: NativeProps['
|
|
112
|
-
|
|
141
|
+
const handleFailedToLoad: NativeProps['onNativeAdFailedToLoad'] = e => {
|
|
142
|
+
onNativeAdFailedToLoad?.(e.nativeEvent);
|
|
113
143
|
};
|
|
114
144
|
|
|
115
|
-
const handleShowFailed: NativeProps['
|
|
116
|
-
|
|
145
|
+
const handleShowFailed: NativeProps['onNativeAdShowFailed'] = e => {
|
|
146
|
+
onNativeAdShowFailed?.(e.nativeEvent);
|
|
117
147
|
};
|
|
118
148
|
|
|
119
149
|
return (
|
|
120
150
|
<NativeComponent
|
|
121
|
-
|
|
122
|
-
{...
|
|
123
|
-
|
|
124
|
-
|
|
151
|
+
collapsable={false}
|
|
152
|
+
{...nativeRest}
|
|
153
|
+
viewSyncKey={viewSyncKey ?? -1}
|
|
154
|
+
loadRequestId={loadRequestIdForNative}
|
|
155
|
+
showRequestId={showRequestIdForNative}
|
|
156
|
+
onNativeAdFailedToLoad={
|
|
157
|
+
onNativeAdFailedToLoad ? handleFailedToLoad : undefined
|
|
158
|
+
}
|
|
159
|
+
onNativeAdShowFailed={
|
|
160
|
+
onNativeAdShowFailed ? handleShowFailed : undefined
|
|
161
|
+
}
|
|
125
162
|
/>
|
|
126
163
|
);
|
|
127
164
|
});
|
package/src/AdWhaleRewardAd.ts
CHANGED
|
@@ -8,8 +8,14 @@ export interface AdWhaleRewardErrorEvent {
|
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
export interface AdWhaleRewardUserRewardedEvent {
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
/** Flutter payload key */
|
|
12
|
+
RewardType?: string;
|
|
13
|
+
/** Flutter payload key */
|
|
14
|
+
RewardAmount?: number;
|
|
15
|
+
/** 레거시 호환 */
|
|
16
|
+
type?: string;
|
|
17
|
+
/** 레거시 호환 */
|
|
18
|
+
amount?: number;
|
|
13
19
|
}
|
|
14
20
|
|
|
15
21
|
export interface AdWhaleRewardEvents {
|
|
@@ -27,59 +33,222 @@ export interface AdWhaleRewardGcoder {
|
|
|
27
33
|
lng: number;
|
|
28
34
|
}
|
|
29
35
|
|
|
36
|
+
/**
|
|
37
|
+
* 보상형 광고 로드 시 함께 지정할 수 있는 옵션.
|
|
38
|
+
* placementName / region / gcoder 는 기존 옵션이며,
|
|
39
|
+
* userId / customData 는 보상형 SSV(서버 사이드 검증) 전용 옵션입니다.
|
|
40
|
+
*/
|
|
41
|
+
export interface AdWhaleRewardLoadOptions {
|
|
42
|
+
placementName?: string;
|
|
43
|
+
region?: string;
|
|
44
|
+
gcoder?: AdWhaleRewardGcoder;
|
|
45
|
+
/**
|
|
46
|
+
* 보상형 SSV(서버 사이드 검증)용 앱 사용자 id.
|
|
47
|
+
* AdMob / AdManager SSV postback 의 user_id 로 전달됩니다.
|
|
48
|
+
* (그 외 네트워크에서는 무시됩니다.)
|
|
49
|
+
*/
|
|
50
|
+
userId?: string;
|
|
51
|
+
/**
|
|
52
|
+
* 보상형 SSV(서버 사이드 검증)용 커스텀 데이터.
|
|
53
|
+
* AdMob / AdManager SSV postback 의 custom_data 로 전달되며,
|
|
54
|
+
* 네이티브에서 JSON 문자열로 직렬화되어 실립니다.
|
|
55
|
+
* (그 외 네트워크에서는 무시됩니다.)
|
|
56
|
+
*/
|
|
57
|
+
customData?: { [key: string]: string };
|
|
58
|
+
}
|
|
59
|
+
|
|
30
60
|
interface RNAdWhaleMediationRewardAdNativeModule {
|
|
31
|
-
setPlacementName(placementName: string): void;
|
|
32
|
-
setRegion(region: string): void;
|
|
33
|
-
setGcoder(gcoder: { lt: number; lng: number }): void;
|
|
34
|
-
|
|
35
|
-
|
|
61
|
+
setPlacementName?(placementName: string): void;
|
|
62
|
+
setRegion?(region: string): void;
|
|
63
|
+
setGcoder?(gcoder: { lt: number; lng: number }): void;
|
|
64
|
+
setUserId?(userId: string): void;
|
|
65
|
+
setCustomData?(customData: { [key: string]: string }): void;
|
|
66
|
+
loadAd?(placementUid: string): void;
|
|
67
|
+
showAd?(): void;
|
|
68
|
+
loadRewardAd?(args: {
|
|
69
|
+
adId: number;
|
|
70
|
+
placementUid: string;
|
|
71
|
+
placementName?: string;
|
|
72
|
+
region?: string;
|
|
73
|
+
gcoder?: [number, number];
|
|
74
|
+
userId?: string;
|
|
75
|
+
customData?: { [key: string]: string };
|
|
76
|
+
}): void;
|
|
77
|
+
showAdWithoutView?(adId: number): void;
|
|
78
|
+
destroyAd?(adId: number): void;
|
|
36
79
|
addListener(eventName: string): void;
|
|
37
80
|
removeListeners(count: number): void;
|
|
38
81
|
}
|
|
39
82
|
|
|
83
|
+
const LINKING_ERROR =
|
|
84
|
+
'RNAdWhaleMediationRewardAd native module is not linked on this platform.';
|
|
85
|
+
|
|
40
86
|
const { RNAdWhaleMediationRewardAd } = NativeModules as {
|
|
41
|
-
RNAdWhaleMediationRewardAd
|
|
87
|
+
RNAdWhaleMediationRewardAd?: RNAdWhaleMediationRewardAdNativeModule;
|
|
42
88
|
};
|
|
43
89
|
|
|
44
|
-
const rewardEmitter =
|
|
90
|
+
const rewardEmitter = RNAdWhaleMediationRewardAd
|
|
91
|
+
? new NativeEventEmitter(RNAdWhaleMediationRewardAd)
|
|
92
|
+
: null;
|
|
45
93
|
|
|
46
94
|
export const AdWhaleRewardAd = {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
95
|
+
/**
|
|
96
|
+
* 보상형 SSV(서버 사이드 검증)용 앱 사용자 id 설정.
|
|
97
|
+
*
|
|
98
|
+
* - AdMob / AdManager 의 SSV postback `user_id` 로 전달됩니다. 그 외 네트워크에서는 무시(no-op)됩니다.
|
|
99
|
+
* - `loadAd()` 호출 전에 설정하는 것을 권장하며, `showAd()` 이전까지 호출할 수 있습니다.
|
|
100
|
+
* - 여러 번 호출하면 마지막 값이 적용됩니다.
|
|
101
|
+
*
|
|
102
|
+
* 참고: `loadAd(placementUid, { userId })` 옵션으로도 동일하게 지정할 수 있습니다.
|
|
103
|
+
*/
|
|
104
|
+
setUserId(userId: string) {
|
|
105
|
+
if (!RNAdWhaleMediationRewardAd) {
|
|
106
|
+
console.warn(LINKING_ERROR);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
RNAdWhaleMediationRewardAd.setUserId?.(userId);
|
|
110
|
+
},
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* 보상형 SSV(서버 사이드 검증)용 커스텀 데이터 설정.
|
|
114
|
+
*
|
|
115
|
+
* - AdMob / AdManager 의 SSV postback `custom_data` 로 전달됩니다. 그 외 네트워크에서는 무시(no-op)됩니다.
|
|
116
|
+
* - 전달한 객체는 네이티브에서 JSON 문자열로 직렬화되어 단일 문자열 필드에 실립니다.
|
|
117
|
+
* 퍼블리셔 서버는 postback 의 `custom_data` 값을 JSON 으로 파싱해야 합니다.
|
|
118
|
+
* - AdMob 의 `custom_data` 는 실무상 200자 정도를 넘기면 잘릴 수 있으니 길이에 유의하세요.
|
|
119
|
+
* - `loadAd()` 호출 전에 설정하는 것을 권장하며, `showAd()` 이전까지 호출할 수 있습니다.
|
|
120
|
+
*
|
|
121
|
+
* 참고: `loadAd(placementUid, { customData })` 옵션으로도 동일하게 지정할 수 있습니다.
|
|
122
|
+
*/
|
|
123
|
+
setCustomData(customData: { [key: string]: string }) {
|
|
124
|
+
if (!RNAdWhaleMediationRewardAd) {
|
|
125
|
+
console.warn(LINKING_ERROR);
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
RNAdWhaleMediationRewardAd.setCustomData?.(customData);
|
|
129
|
+
},
|
|
130
|
+
|
|
131
|
+
loadAd(placementUid: string, options?: AdWhaleRewardLoadOptions) {
|
|
132
|
+
if (!RNAdWhaleMediationRewardAd) {
|
|
133
|
+
console.warn(LINKING_ERROR);
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
55
136
|
// 먼저 옵션들을 설정
|
|
56
137
|
if (options?.placementName) {
|
|
57
|
-
RNAdWhaleMediationRewardAd.setPlacementName(options.placementName);
|
|
138
|
+
RNAdWhaleMediationRewardAd.setPlacementName?.(options.placementName);
|
|
58
139
|
}
|
|
59
140
|
if (options?.region) {
|
|
60
|
-
RNAdWhaleMediationRewardAd.setRegion(options.region);
|
|
141
|
+
RNAdWhaleMediationRewardAd.setRegion?.(options.region);
|
|
61
142
|
}
|
|
62
143
|
if (options?.gcoder) {
|
|
63
|
-
RNAdWhaleMediationRewardAd.setGcoder(options.gcoder);
|
|
144
|
+
RNAdWhaleMediationRewardAd.setGcoder?.(options.gcoder);
|
|
145
|
+
}
|
|
146
|
+
// 보상형 SSV(서버 사이드 검증) 옵션
|
|
147
|
+
if (options?.userId) {
|
|
148
|
+
RNAdWhaleMediationRewardAd.setUserId?.(options.userId);
|
|
149
|
+
}
|
|
150
|
+
if (options?.customData) {
|
|
151
|
+
RNAdWhaleMediationRewardAd.setCustomData?.(options.customData);
|
|
152
|
+
}
|
|
153
|
+
if (RNAdWhaleMediationRewardAd.loadAd) {
|
|
154
|
+
RNAdWhaleMediationRewardAd.loadAd(placementUid);
|
|
155
|
+
return;
|
|
64
156
|
}
|
|
65
|
-
|
|
66
|
-
|
|
157
|
+
if (RNAdWhaleMediationRewardAd.loadRewardAd) {
|
|
158
|
+
RNAdWhaleMediationRewardAd.loadRewardAd({
|
|
159
|
+
adId: 0,
|
|
160
|
+
placementUid,
|
|
161
|
+
placementName: options?.placementName,
|
|
162
|
+
region: options?.region,
|
|
163
|
+
gcoder: options?.gcoder
|
|
164
|
+
? [options.gcoder.lt, options.gcoder.lng]
|
|
165
|
+
: undefined,
|
|
166
|
+
userId: options?.userId,
|
|
167
|
+
customData: options?.customData,
|
|
168
|
+
});
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
console.warn(
|
|
172
|
+
'[AdWhaleRewardAd] Native module missing both loadAd and loadRewardAd.',
|
|
173
|
+
);
|
|
67
174
|
},
|
|
68
175
|
|
|
69
176
|
showAd() {
|
|
70
|
-
RNAdWhaleMediationRewardAd
|
|
177
|
+
if (!RNAdWhaleMediationRewardAd) {
|
|
178
|
+
console.warn(LINKING_ERROR);
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
if (RNAdWhaleMediationRewardAd.showAd) {
|
|
182
|
+
RNAdWhaleMediationRewardAd.showAd();
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
if (RNAdWhaleMediationRewardAd.showAdWithoutView) {
|
|
186
|
+
RNAdWhaleMediationRewardAd.showAdWithoutView(0);
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
console.warn(
|
|
190
|
+
'[AdWhaleRewardAd] Native module missing both showAd and showAdWithoutView.',
|
|
191
|
+
);
|
|
192
|
+
},
|
|
193
|
+
|
|
194
|
+
/** Flutter와 동일한 신규 API (권장) */
|
|
195
|
+
loadRewardAd(
|
|
196
|
+
adId: number,
|
|
197
|
+
placementUid: string,
|
|
198
|
+
options?: AdWhaleRewardLoadOptions,
|
|
199
|
+
) {
|
|
200
|
+
if (!RNAdWhaleMediationRewardAd) {
|
|
201
|
+
console.warn(LINKING_ERROR);
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
if (!RNAdWhaleMediationRewardAd.loadRewardAd) {
|
|
205
|
+
this.loadAd(placementUid, options);
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
RNAdWhaleMediationRewardAd.loadRewardAd({
|
|
209
|
+
adId,
|
|
210
|
+
placementUid,
|
|
211
|
+
placementName: options?.placementName,
|
|
212
|
+
region: options?.region,
|
|
213
|
+
gcoder: options?.gcoder ? [options.gcoder.lt, options.gcoder.lng] : undefined,
|
|
214
|
+
userId: options?.userId,
|
|
215
|
+
customData: options?.customData,
|
|
216
|
+
});
|
|
217
|
+
},
|
|
218
|
+
|
|
219
|
+
showAdWithoutView(adId: number) {
|
|
220
|
+
if (!RNAdWhaleMediationRewardAd) {
|
|
221
|
+
console.warn(LINKING_ERROR);
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
if (!RNAdWhaleMediationRewardAd.showAdWithoutView) {
|
|
225
|
+
this.showAd();
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
RNAdWhaleMediationRewardAd.showAdWithoutView(adId);
|
|
229
|
+
},
|
|
230
|
+
|
|
231
|
+
destroyAd(adId: number) {
|
|
232
|
+
RNAdWhaleMediationRewardAd?.destroyAd?.(adId);
|
|
71
233
|
},
|
|
72
234
|
|
|
73
235
|
addEventListeners(listeners: AdWhaleRewardEvents): EmitterSubscription[] {
|
|
236
|
+
if (!rewardEmitter) {
|
|
237
|
+
console.warn(LINKING_ERROR);
|
|
238
|
+
return [];
|
|
239
|
+
}
|
|
74
240
|
const subs: EmitterSubscription[] = [];
|
|
241
|
+
let directShowedReceived = false;
|
|
242
|
+
let directUserRewardedReceived = false;
|
|
75
243
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
244
|
+
subs.push(
|
|
245
|
+
rewardEmitter.addListener('onRewardAdLoaded', () => {
|
|
246
|
+
directShowedReceived = false;
|
|
247
|
+
directUserRewardedReceived = false;
|
|
248
|
+
console.log('AdWhaleRewardAd.ts Reward onLoaded');
|
|
249
|
+
listeners.onLoaded?.();
|
|
250
|
+
}),
|
|
251
|
+
);
|
|
83
252
|
if (listeners.onLoadFailed) {
|
|
84
253
|
subs.push(
|
|
85
254
|
rewardEmitter.addListener(
|
|
@@ -88,13 +257,13 @@ export const AdWhaleRewardAd = {
|
|
|
88
257
|
),
|
|
89
258
|
);
|
|
90
259
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
)
|
|
97
|
-
|
|
260
|
+
subs.push(
|
|
261
|
+
rewardEmitter.addListener('onRewardAdShowed', () => {
|
|
262
|
+
directShowedReceived = true;
|
|
263
|
+
console.log('AdWhaleRewardAd.ts Reward onAdShowed');
|
|
264
|
+
listeners.onShowed?.();
|
|
265
|
+
}),
|
|
266
|
+
);
|
|
98
267
|
if (listeners.onShowFailed) {
|
|
99
268
|
subs.push(
|
|
100
269
|
rewardEmitter.addListener(
|
|
@@ -103,13 +272,14 @@ export const AdWhaleRewardAd = {
|
|
|
103
272
|
),
|
|
104
273
|
);
|
|
105
274
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
275
|
+
subs.push(
|
|
276
|
+
rewardEmitter.addListener('onRewardAdDismissed', () => {
|
|
277
|
+
directShowedReceived = false;
|
|
278
|
+
directUserRewardedReceived = false;
|
|
279
|
+
console.log('AdWhaleRewardAd.ts Reward onDismissed');
|
|
280
|
+
listeners.onDismissed?.();
|
|
281
|
+
}),
|
|
282
|
+
);
|
|
113
283
|
if (listeners.onClicked) {
|
|
114
284
|
subs.push(
|
|
115
285
|
rewardEmitter.addListener('onRewardAdClicked', () => {
|
|
@@ -117,15 +287,111 @@ export const AdWhaleRewardAd = {
|
|
|
117
287
|
}),
|
|
118
288
|
);
|
|
119
289
|
}
|
|
120
|
-
|
|
290
|
+
subs.push(
|
|
291
|
+
rewardEmitter.addListener(
|
|
292
|
+
'onUserRewarded',
|
|
293
|
+
event => {
|
|
294
|
+
directUserRewardedReceived = true;
|
|
295
|
+
const rewardedEvent = event as AdWhaleRewardUserRewardedEvent;
|
|
296
|
+
const rewardAmount = rewardedEvent.amount ?? rewardedEvent.RewardAmount;
|
|
297
|
+
const rewardType = rewardedEvent.type ?? rewardedEvent.RewardType;
|
|
298
|
+
console.log(
|
|
299
|
+
`AdWhaleRewardAd.ts Reward onUserRewarded: ${String(rewardAmount)}, ${String(rewardType)}`,
|
|
300
|
+
);
|
|
301
|
+
listeners.onUserRewarded?.(rewardedEvent);
|
|
302
|
+
},
|
|
303
|
+
),
|
|
304
|
+
);
|
|
305
|
+
subs.push(
|
|
306
|
+
rewardEmitter.addListener('onAdEvent', (payload: any) => {
|
|
307
|
+
if (payload?.eventName === 'onRewardAdShowed' && !directShowedReceived) {
|
|
308
|
+
directShowedReceived = true;
|
|
309
|
+
console.log('AdWhaleRewardAd.ts Reward onAdShowed');
|
|
310
|
+
listeners.onShowed?.();
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
if (payload?.eventName === 'onUserRewarded' && !directUserRewardedReceived) {
|
|
315
|
+
directUserRewardedReceived = true;
|
|
316
|
+
const rewardAmount = payload?.amount ?? payload?.RewardAmount;
|
|
317
|
+
const rewardType = payload?.type ?? payload?.RewardType;
|
|
318
|
+
console.log(
|
|
319
|
+
`AdWhaleRewardAd.ts Reward onUserRewarded: ${String(rewardAmount)}, ${String(rewardType)}`,
|
|
320
|
+
);
|
|
321
|
+
listeners.onUserRewarded?.({
|
|
322
|
+
RewardType: payload?.RewardType,
|
|
323
|
+
RewardAmount: payload?.RewardAmount,
|
|
324
|
+
type: payload?.type,
|
|
325
|
+
amount: payload?.amount,
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
}),
|
|
329
|
+
);
|
|
330
|
+
|
|
331
|
+
return subs;
|
|
332
|
+
},
|
|
333
|
+
|
|
334
|
+
/** Flutter `onAdEvent` 스타일 (adId 필터링) */
|
|
335
|
+
addAdEventListenersById(
|
|
336
|
+
adId: number,
|
|
337
|
+
listeners: AdWhaleRewardEvents,
|
|
338
|
+
): EmitterSubscription[] {
|
|
339
|
+
if (!rewardEmitter) {
|
|
340
|
+
console.warn(LINKING_ERROR);
|
|
341
|
+
return [];
|
|
342
|
+
}
|
|
343
|
+
const subs: EmitterSubscription[] = [];
|
|
344
|
+
|
|
345
|
+
const handle = (eventName: string, cb?: (p?: any) => void) => {
|
|
346
|
+
if (!cb) return;
|
|
121
347
|
subs.push(
|
|
122
|
-
rewardEmitter.addListener(
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
348
|
+
rewardEmitter.addListener('onAdEvent', (payload: any) => {
|
|
349
|
+
if (!payload || payload.adId !== adId || payload.eventName !== eventName) {
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
cb(payload);
|
|
353
|
+
}),
|
|
127
354
|
);
|
|
128
|
-
}
|
|
355
|
+
};
|
|
356
|
+
|
|
357
|
+
handle('onRewardAdLoaded', () => {
|
|
358
|
+
console.log('AdWhaleRewardAd.ts Reward onLoaded');
|
|
359
|
+
listeners.onLoaded?.();
|
|
360
|
+
});
|
|
361
|
+
handle('onRewardAdFailedToLoad', p =>
|
|
362
|
+
listeners.onLoadFailed?.({
|
|
363
|
+
statusCode: Number(p?.statusCode ?? -1),
|
|
364
|
+
message: String(p?.message ?? ''),
|
|
365
|
+
}),
|
|
366
|
+
);
|
|
367
|
+
handle('onRewardAdShowed', () => {
|
|
368
|
+
console.log('AdWhaleRewardAd.ts Reward onAdShowed');
|
|
369
|
+
listeners.onShowed?.();
|
|
370
|
+
});
|
|
371
|
+
handle('onRewardAdFailedToShow', p =>
|
|
372
|
+
listeners.onShowFailed?.({
|
|
373
|
+
statusCode: Number(p?.statusCode ?? -1),
|
|
374
|
+
message: String(p?.message ?? ''),
|
|
375
|
+
}),
|
|
376
|
+
);
|
|
377
|
+
handle('onRewardAdDismissed', () => {
|
|
378
|
+
console.log('AdWhaleRewardAd.ts Reward onDismissed');
|
|
379
|
+
listeners.onDismissed?.();
|
|
380
|
+
});
|
|
381
|
+
handle('onRewardAdClicked', () => listeners.onClicked?.());
|
|
382
|
+
handle('onUserRewarded', p => {
|
|
383
|
+
const rewardAmount = p?.amount ?? p?.RewardAmount;
|
|
384
|
+
const rewardType = p?.type ?? p?.RewardType;
|
|
385
|
+
console.log(
|
|
386
|
+
`AdWhaleRewardAd.ts Reward onUserRewarded: ${String(rewardAmount)}, ${String(rewardType)}`,
|
|
387
|
+
);
|
|
388
|
+
listeners.onUserRewarded?.({
|
|
389
|
+
RewardType: p?.RewardType,
|
|
390
|
+
RewardAmount: p?.RewardAmount,
|
|
391
|
+
type: p?.type,
|
|
392
|
+
amount: p?.amount,
|
|
393
|
+
});
|
|
394
|
+
});
|
|
129
395
|
|
|
130
396
|
return subs;
|
|
131
397
|
},
|