cloudx-react-native 2.0.0-beta.1 → 2.2.3
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/README.md +420 -1046
- package/android/build.gradle +1 -2
- package/android/src/main/AndroidManifest.xml +0 -4
- package/android/src/main/java/com/cloudxreactnative/CloudXAdEvents.kt +39 -0
- package/android/src/main/java/com/cloudxreactnative/CloudXAdInfo.kt +32 -0
- package/android/src/main/java/com/cloudxreactnative/CloudXModuleImpl.kt +694 -0
- package/android/src/{newarch/com/cloudxreactnative/CloudXReactNativePackage.kt → main/java/com/cloudxreactnative/CloudXPackage.kt} +14 -13
- package/android/src/newarch/com/cloudxreactnative/{CloudXReactNativeModule.kt → CloudXModule.kt} +31 -34
- package/android/src/oldarch/com/cloudxreactnative/{CloudXReactNativeModule.kt → CloudXModule.kt} +27 -32
- package/cloudx-react-native.podspec +1 -1
- package/ios/CloudX.h +47 -0
- package/ios/CloudX.mm +1406 -0
- package/lib/commonjs/AppTrackingTransparency.js +13 -13
- package/lib/commonjs/AppTrackingTransparency.js.map +1 -1
- package/lib/commonjs/CloudX.js +16 -12
- package/lib/commonjs/CloudX.js.map +1 -1
- package/lib/commonjs/CloudXAdPosition.js +23 -0
- package/lib/commonjs/CloudXAdPosition.js.map +1 -0
- package/lib/commonjs/{BannerAd.js → CloudXBannerAd.js} +42 -37
- package/lib/commonjs/CloudXBannerAd.js.map +1 -0
- package/lib/commonjs/CloudXErrorCode.js +116 -0
- package/lib/commonjs/CloudXErrorCode.js.map +1 -0
- package/lib/commonjs/{InterstitialAd.js → CloudXInterstitialAd.js} +10 -10
- package/lib/commonjs/CloudXInterstitialAd.js.map +1 -0
- package/lib/commonjs/{MRecAd.js → CloudXMRECAd.js} +42 -37
- package/lib/commonjs/CloudXMRECAd.js.map +1 -0
- package/lib/commonjs/{RewardedAd.js → CloudXRewardedAd.js} +10 -10
- package/lib/commonjs/CloudXRewardedAd.js.map +1 -0
- package/lib/commonjs/EventEmitter.js +3 -3
- package/lib/commonjs/EventEmitter.js.map +1 -1
- package/lib/commonjs/hooks.js +25 -26
- package/lib/commonjs/hooks.js.map +1 -1
- package/lib/commonjs/index.js +27 -41
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/specs/{NativeCloudXModule.js → NativeCloudX.js} +2 -2
- package/lib/commonjs/specs/NativeCloudX.js.map +1 -0
- package/lib/commonjs/types/AdProps.js +6 -0
- package/lib/commonjs/types/AdProps.js.map +1 -0
- package/lib/commonjs/types/InterstitialAd.js +6 -0
- package/lib/commonjs/types/InterstitialAd.js.map +1 -0
- package/lib/commonjs/types/MRECAd.js +6 -0
- package/lib/commonjs/types/MRECAd.js.map +1 -0
- package/lib/commonjs/types/ViewAd.js +6 -0
- package/lib/commonjs/types/ViewAd.js.map +1 -0
- package/lib/module/AppTrackingTransparency.js +12 -12
- package/lib/module/AppTrackingTransparency.js.map +1 -1
- package/lib/module/CloudX.js +16 -12
- package/lib/module/CloudX.js.map +1 -1
- package/lib/module/CloudXAdPosition.js +17 -0
- package/lib/module/CloudXAdPosition.js.map +1 -0
- package/lib/module/{BannerAd.js → CloudXBannerAd.js} +41 -36
- package/lib/module/CloudXBannerAd.js.map +1 -0
- package/lib/module/CloudXErrorCode.js +110 -0
- package/lib/module/CloudXErrorCode.js.map +1 -0
- package/lib/module/{InterstitialAd.js → CloudXInterstitialAd.js} +9 -9
- package/lib/module/CloudXInterstitialAd.js.map +1 -0
- package/lib/module/{MRecAd.js → CloudXMRECAd.js} +41 -36
- package/lib/module/CloudXMRECAd.js.map +1 -0
- package/lib/module/{RewardedAd.js → CloudXRewardedAd.js} +9 -9
- package/lib/module/CloudXRewardedAd.js.map +1 -0
- package/lib/module/EventEmitter.js +2 -2
- package/lib/module/EventEmitter.js.map +1 -1
- package/lib/module/hooks.js +14 -15
- package/lib/module/hooks.js.map +1 -1
- package/lib/module/index.js +9 -10
- package/lib/module/index.js.map +1 -1
- package/lib/module/specs/{NativeCloudXModule.js → NativeCloudX.js} +2 -2
- package/lib/module/specs/NativeCloudX.js.map +1 -0
- package/lib/module/types/AdProps.js +2 -0
- package/lib/module/types/AdProps.js.map +1 -0
- package/lib/module/types/InterstitialAd.js +2 -0
- package/lib/module/types/InterstitialAd.js.map +1 -0
- package/lib/module/types/MRECAd.js +2 -0
- package/lib/module/types/MRECAd.js.map +1 -0
- package/lib/module/types/ViewAd.js +2 -0
- package/lib/module/types/ViewAd.js.map +1 -0
- package/lib/typescript/src/AppTrackingTransparency.d.ts +4 -4
- package/lib/typescript/src/AppTrackingTransparency.d.ts.map +1 -1
- package/lib/typescript/src/CloudX.d.ts.map +1 -1
- package/lib/typescript/src/CloudXAdPosition.d.ts +16 -0
- package/lib/typescript/src/CloudXAdPosition.d.ts.map +1 -0
- package/lib/typescript/src/CloudXBannerAd.d.ts +4 -0
- package/lib/typescript/src/CloudXBannerAd.d.ts.map +1 -0
- package/lib/typescript/src/{ErrorCode.d.ts → CloudXErrorCode.d.ts} +2 -2
- package/lib/typescript/src/CloudXErrorCode.d.ts.map +1 -0
- package/lib/typescript/src/CloudXInterstitialAd.d.ts +4 -0
- package/lib/typescript/src/CloudXInterstitialAd.d.ts.map +1 -0
- package/lib/typescript/src/CloudXMRECAd.d.ts +4 -0
- package/lib/typescript/src/CloudXMRECAd.d.ts.map +1 -0
- package/lib/typescript/src/CloudXRewardedAd.d.ts +4 -0
- package/lib/typescript/src/CloudXRewardedAd.d.ts.map +1 -0
- package/lib/typescript/src/EventEmitter.d.ts +4 -2
- package/lib/typescript/src/EventEmitter.d.ts.map +1 -1
- package/lib/typescript/src/hooks.d.ts +7 -8
- package/lib/typescript/src/hooks.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +12 -13
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/specs/{NativeCloudXModule.d.ts → NativeCloudX.d.ts} +47 -64
- package/lib/typescript/src/specs/NativeCloudX.d.ts.map +1 -0
- package/lib/typescript/src/types/AdEvent.d.ts +3 -3
- package/lib/typescript/src/types/AdEvent.d.ts.map +1 -1
- package/lib/typescript/src/types/AdInfo.d.ts +7 -7
- package/lib/typescript/src/types/AdInfo.d.ts.map +1 -1
- package/lib/typescript/src/types/AdProps.d.ts +21 -0
- package/lib/typescript/src/types/AdProps.d.ts.map +1 -0
- package/lib/typescript/src/types/BannerAd.d.ts +8 -34
- package/lib/typescript/src/types/BannerAd.d.ts.map +1 -1
- package/lib/typescript/src/types/CloudX.d.ts +7 -4
- package/lib/typescript/src/types/CloudX.d.ts.map +1 -1
- package/lib/typescript/src/types/Configuration.d.ts +7 -3
- package/lib/typescript/src/types/Configuration.d.ts.map +1 -1
- package/lib/typescript/src/types/FullscreenAd.d.ts +10 -9
- package/lib/typescript/src/types/FullscreenAd.d.ts.map +1 -1
- package/lib/typescript/src/types/InterstitialAd.d.ts +8 -0
- package/lib/typescript/src/types/InterstitialAd.d.ts.map +1 -0
- package/lib/typescript/src/types/MRECAd.d.ts +13 -0
- package/lib/typescript/src/types/MRECAd.d.ts.map +1 -0
- package/lib/typescript/src/types/RewardedAd.d.ts +5 -4
- package/lib/typescript/src/types/RewardedAd.d.ts.map +1 -1
- package/lib/typescript/src/types/ViewAd.d.ts +29 -0
- package/lib/typescript/src/types/ViewAd.d.ts.map +1 -0
- package/lib/typescript/src/types/index.d.ts +11 -7
- package/lib/typescript/src/types/index.d.ts.map +1 -1
- package/package.json +8 -10
- package/src/AppTrackingTransparency.ts +10 -10
- package/src/CloudX.ts +21 -16
- package/src/CloudXAdPosition.ts +16 -0
- package/src/{BannerAd.ts → CloudXBannerAd.ts} +69 -47
- package/src/{ErrorCode.ts → CloudXErrorCode.ts} +1 -1
- package/src/{InterstitialAd.ts → CloudXInterstitialAd.ts} +17 -17
- package/src/{MRecAd.ts → CloudXMRECAd.ts} +69 -47
- package/src/{RewardedAd.ts → CloudXRewardedAd.ts} +18 -18
- package/src/EventEmitter.ts +4 -4
- package/src/hooks.ts +20 -22
- package/src/index.ts +27 -24
- package/src/specs/{NativeCloudXModule.ts → NativeCloudX.ts} +61 -82
- package/src/types/AdEvent.ts +3 -3
- package/src/types/AdInfo.ts +7 -7
- package/src/types/AdProps.ts +27 -0
- package/src/types/BannerAd.ts +8 -54
- package/src/types/CloudX.ts +10 -5
- package/src/types/Configuration.ts +8 -3
- package/src/types/FullscreenAd.ts +10 -9
- package/src/types/InterstitialAd.ts +8 -0
- package/src/types/MRECAd.ts +13 -0
- package/src/types/RewardedAd.ts +5 -4
- package/src/types/ViewAd.ts +38 -0
- package/src/types/index.ts +11 -7
- package/android/src/main/java/com/cloudxreactnative/CloudXAdViewEvent.kt +0 -15
- package/android/src/main/java/com/cloudxreactnative/CloudXBannerViewManagerImpl.kt +0 -472
- package/android/src/main/java/com/cloudxreactnative/CloudXReactNativeModuleImpl.kt +0 -861
- package/android/src/newarch/com/cloudxreactnative/CloudXBannerViewManager.kt +0 -90
- package/android/src/oldarch/com/cloudxreactnative/CloudXBannerViewManager.kt +0 -76
- package/android/src/oldarch/com/cloudxreactnative/CloudXReactNativePackage.kt +0 -16
- package/ios/RNCloudXBannerView.h +0 -51
- package/ios/RNCloudXBannerView.mm +0 -633
- package/ios/RNCloudXBannerViewManager.h +0 -11
- package/ios/RNCloudXBannerViewManager.mm +0 -60
- package/ios/RNCloudXModule.h +0 -30
- package/ios/RNCloudXModule.mm +0 -1088
- package/lib/commonjs/AdView.js +0 -151
- package/lib/commonjs/AdView.js.map +0 -1
- package/lib/commonjs/BannerAd.js.map +0 -1
- package/lib/commonjs/ErrorCode.js +0 -116
- package/lib/commonjs/ErrorCode.js.map +0 -1
- package/lib/commonjs/InterstitialAd.js.map +0 -1
- package/lib/commonjs/MRecAd.js.map +0 -1
- package/lib/commonjs/RewardedAd.js.map +0 -1
- package/lib/commonjs/specs/CloudXAdViewNativeComponent.js +0 -26
- package/lib/commonjs/specs/CloudXAdViewNativeComponent.js.map +0 -1
- package/lib/commonjs/specs/NativeCloudXModule.js.map +0 -1
- package/lib/module/AdView.js +0 -144
- package/lib/module/AdView.js.map +0 -1
- package/lib/module/BannerAd.js.map +0 -1
- package/lib/module/ErrorCode.js +0 -110
- package/lib/module/ErrorCode.js.map +0 -1
- package/lib/module/InterstitialAd.js.map +0 -1
- package/lib/module/MRecAd.js.map +0 -1
- package/lib/module/RewardedAd.js.map +0 -1
- package/lib/module/specs/CloudXAdViewNativeComponent.js +0 -20
- package/lib/module/specs/CloudXAdViewNativeComponent.js.map +0 -1
- package/lib/module/specs/NativeCloudXModule.js.map +0 -1
- package/lib/typescript/src/AdView.d.ts +0 -69
- package/lib/typescript/src/AdView.d.ts.map +0 -1
- package/lib/typescript/src/BannerAd.d.ts +0 -4
- package/lib/typescript/src/BannerAd.d.ts.map +0 -1
- package/lib/typescript/src/ErrorCode.d.ts.map +0 -1
- package/lib/typescript/src/InterstitialAd.d.ts +0 -4
- package/lib/typescript/src/InterstitialAd.d.ts.map +0 -1
- package/lib/typescript/src/MRecAd.d.ts +0 -4
- package/lib/typescript/src/MRecAd.d.ts.map +0 -1
- package/lib/typescript/src/RewardedAd.d.ts +0 -4
- package/lib/typescript/src/RewardedAd.d.ts.map +0 -1
- package/lib/typescript/src/specs/CloudXAdViewNativeComponent.d.ts +0 -61
- package/lib/typescript/src/specs/CloudXAdViewNativeComponent.d.ts.map +0 -1
- package/lib/typescript/src/specs/NativeCloudXModule.d.ts.map +0 -1
- package/src/AdView.tsx +0 -213
- package/src/specs/CloudXAdViewNativeComponent.ts +0 -82
|
@@ -1,472 +0,0 @@
|
|
|
1
|
-
package com.cloudxreactnative
|
|
2
|
-
|
|
3
|
-
import android.os.Build
|
|
4
|
-
import android.util.Log
|
|
5
|
-
import android.view.Gravity
|
|
6
|
-
import android.view.View
|
|
7
|
-
import android.view.ViewGroup
|
|
8
|
-
import android.view.WindowInsets
|
|
9
|
-
import android.widget.FrameLayout
|
|
10
|
-
import com.facebook.react.bridge.Arguments
|
|
11
|
-
import com.facebook.react.bridge.ReactApplicationContext
|
|
12
|
-
import com.facebook.react.bridge.WritableMap
|
|
13
|
-
import com.facebook.react.common.MapBuilder
|
|
14
|
-
import com.facebook.react.uimanager.ThemedReactContext
|
|
15
|
-
import com.facebook.react.uimanager.UIManagerHelper
|
|
16
|
-
import io.cloudx.sdk.*
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Ad view position options for programmatic banner placement.
|
|
20
|
-
* Used for programmatic banner placement.
|
|
21
|
-
*/
|
|
22
|
-
enum class AdViewPosition {
|
|
23
|
-
NONE, // Use React Native layout (default)
|
|
24
|
-
TOP_LEFT,
|
|
25
|
-
TOP_CENTER,
|
|
26
|
-
TOP_RIGHT,
|
|
27
|
-
CENTER_LEFT,
|
|
28
|
-
CENTERED,
|
|
29
|
-
CENTER_RIGHT,
|
|
30
|
-
BOTTOM_LEFT,
|
|
31
|
-
BOTTOM_CENTER,
|
|
32
|
-
BOTTOM_RIGHT;
|
|
33
|
-
|
|
34
|
-
companion object {
|
|
35
|
-
fun fromString(value: String?): AdViewPosition {
|
|
36
|
-
return when (value?.uppercase()) {
|
|
37
|
-
"TOP_LEFT" -> TOP_LEFT
|
|
38
|
-
"TOP_CENTER" -> TOP_CENTER
|
|
39
|
-
"TOP_RIGHT" -> TOP_RIGHT
|
|
40
|
-
"CENTER_LEFT" -> CENTER_LEFT
|
|
41
|
-
"CENTERED" -> CENTERED
|
|
42
|
-
"CENTER_RIGHT" -> CENTER_RIGHT
|
|
43
|
-
"BOTTOM_LEFT" -> BOTTOM_LEFT
|
|
44
|
-
"BOTTOM_CENTER" -> BOTTOM_CENTER
|
|
45
|
-
"BOTTOM_RIGHT" -> BOTTOM_RIGHT
|
|
46
|
-
else -> NONE
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Wrapper view that holds a CloudXAdView
|
|
54
|
-
* This allows us to create the ad AFTER props are set
|
|
55
|
-
*/
|
|
56
|
-
class CloudXBannerViewWrapper(context: ThemedReactContext) : FrameLayout(context) {
|
|
57
|
-
var placement: String? = null
|
|
58
|
-
var adId: String? = null
|
|
59
|
-
var adType: String? = null
|
|
60
|
-
var position: String? = null
|
|
61
|
-
var customData: String? = null
|
|
62
|
-
var autoRefresh: Boolean = true
|
|
63
|
-
var shouldLoad: Boolean = false
|
|
64
|
-
var hasCreatedAd: Boolean = false
|
|
65
|
-
var isDestroyed: Boolean = false
|
|
66
|
-
var cloudXAdView: CloudXAdView? = null
|
|
67
|
-
var isUsingWindowPositioning: Boolean = false
|
|
68
|
-
val reactContext: ThemedReactContext = context
|
|
69
|
-
|
|
70
|
-
init {
|
|
71
|
-
clipChildren = false
|
|
72
|
-
clipToPadding = false
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
override fun onDetachedFromWindow() {
|
|
76
|
-
super.onDetachedFromWindow()
|
|
77
|
-
cloudXAdView?.stopAutoRefresh()
|
|
78
|
-
if (isUsingWindowPositioning) {
|
|
79
|
-
removeAdFromWindow()
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
override fun onAttachedToWindow() {
|
|
84
|
-
super.onAttachedToWindow()
|
|
85
|
-
if (autoRefresh) {
|
|
86
|
-
cloudXAdView?.startAutoRefresh()
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
fun removeAdFromWindow() {
|
|
91
|
-
cloudXAdView?.let { adView ->
|
|
92
|
-
(adView.parent as? ViewGroup)?.removeView(adView)
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
override fun requestLayout() {
|
|
97
|
-
super.requestLayout()
|
|
98
|
-
if (isUsingWindowPositioning) return
|
|
99
|
-
// No-op: ad views are always placed in the Activity's content frame
|
|
100
|
-
// (see addAdAsSubview). requestLayout is not needed for subview mode
|
|
101
|
-
// because we position via window overlay at the wrapper's coordinates.
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Shared implementation for CloudXBannerViewManager
|
|
107
|
-
* Used by both old and new architecture
|
|
108
|
-
*/
|
|
109
|
-
object CloudXBannerViewManagerImpl {
|
|
110
|
-
const val NAME = "CloudXAdView"
|
|
111
|
-
private const val TAG = "CloudXBannerViewManager"
|
|
112
|
-
|
|
113
|
-
fun createViewInstance(reactContext: ThemedReactContext): CloudXBannerViewWrapper {
|
|
114
|
-
return CloudXBannerViewWrapper(reactContext)
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
fun setPlacement(view: CloudXBannerViewWrapper, placement: String?) {
|
|
118
|
-
view.placement = placement
|
|
119
|
-
view.cloudXAdView?.setPlacement(placement)
|
|
120
|
-
maybeCreateAdView(view)
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
fun setAdId(view: CloudXBannerViewWrapper, adId: String?) {
|
|
124
|
-
view.adId = adId
|
|
125
|
-
maybeCreateAdView(view)
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
fun setAdType(view: CloudXBannerViewWrapper, adType: String?) {
|
|
129
|
-
val oldType = view.adType
|
|
130
|
-
view.adType = adType
|
|
131
|
-
// Destroy and recreate if format changed on an already-mounted ad,
|
|
132
|
-
// since banner and MREC use different native SDK creation methods.
|
|
133
|
-
if (view.hasCreatedAd && oldType != null && oldType != adType) {
|
|
134
|
-
onDropViewInstance(view)
|
|
135
|
-
view.hasCreatedAd = false
|
|
136
|
-
view.isDestroyed = false
|
|
137
|
-
maybeCreateAdView(view)
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
fun setPosition(view: CloudXBannerViewWrapper, position: String?) {
|
|
142
|
-
view.position = position
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
fun setCustomData(view: CloudXBannerViewWrapper, customData: String?) {
|
|
146
|
-
view.customData = customData
|
|
147
|
-
view.cloudXAdView?.setCustomData(customData)
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
fun setAutoRefresh(view: CloudXBannerViewWrapper, autoRefresh: Boolean) {
|
|
151
|
-
view.autoRefresh = autoRefresh
|
|
152
|
-
view.cloudXAdView?.let { adView ->
|
|
153
|
-
if (autoRefresh) adView.startAutoRefresh() else adView.stopAutoRefresh()
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
fun setShouldLoad(view: CloudXBannerViewWrapper, shouldLoad: Boolean) {
|
|
158
|
-
view.shouldLoad = shouldLoad
|
|
159
|
-
maybeCreateAdView(view)
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
fun onAfterUpdateTransaction(view: CloudXBannerViewWrapper) {
|
|
163
|
-
if (view.isDestroyed) {
|
|
164
|
-
view.hasCreatedAd = false
|
|
165
|
-
view.isDestroyed = false
|
|
166
|
-
view.isUsingWindowPositioning = false
|
|
167
|
-
}
|
|
168
|
-
maybeCreateAdView(view)
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
private fun maybeCreateAdView(view: CloudXBannerViewWrapper) {
|
|
172
|
-
if (view.shouldLoad && !view.hasCreatedAd && view.adId != null) {
|
|
173
|
-
// Defer to next run loop so all props are set before creation,
|
|
174
|
-
// matching iOS dispatch_async(dispatch_get_main_queue()) pattern
|
|
175
|
-
view.post {
|
|
176
|
-
if (!view.hasCreatedAd && !view.isDestroyed) {
|
|
177
|
-
createAndLoadAd(view)
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
private fun createAndLoadAd(view: CloudXBannerViewWrapper) {
|
|
184
|
-
val adId = view.adId ?: return
|
|
185
|
-
val adType = view.adType ?: "BANNER"
|
|
186
|
-
|
|
187
|
-
val cloudXAdView = when (adType.uppercase()) {
|
|
188
|
-
"MREC" -> CloudX.createMREC(adId)
|
|
189
|
-
else -> CloudX.createBanner(adId)
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
view.cloudXAdView = cloudXAdView
|
|
193
|
-
view.hasCreatedAd = true
|
|
194
|
-
|
|
195
|
-
view.placement?.let { cloudXAdView.setPlacement(it) }
|
|
196
|
-
view.customData?.let { cloudXAdView.setCustomData(it) }
|
|
197
|
-
|
|
198
|
-
// Set up listeners BEFORE adding to view hierarchy
|
|
199
|
-
setupListeners(view, cloudXAdView, adId)
|
|
200
|
-
|
|
201
|
-
// Check if we should use programmatic window positioning
|
|
202
|
-
val adPosition = AdViewPosition.fromString(view.position)
|
|
203
|
-
val isMREC = adType.uppercase() == "MREC"
|
|
204
|
-
|
|
205
|
-
if (adPosition != AdViewPosition.NONE) {
|
|
206
|
-
addAdToWindow(view, cloudXAdView, adPosition, isMREC)
|
|
207
|
-
} else {
|
|
208
|
-
addAdAsSubview(view, cloudXAdView)
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
if (!view.autoRefresh) {
|
|
212
|
-
cloudXAdView.stopAutoRefresh()
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
view.post {
|
|
216
|
-
if (!view.isDestroyed) {
|
|
217
|
-
cloudXAdView.load()
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
private fun addAdAsSubview(wrapper: CloudXBannerViewWrapper, adView: CloudXAdView) {
|
|
223
|
-
// The CloudX SDK's visibility detection (background→foreground layer promotion)
|
|
224
|
-
// only works when CXAdView is in the Activity's native view hierarchy, not when
|
|
225
|
-
// nested inside React Native's Yoga-managed views. To work around this, we add
|
|
226
|
-
// the ad to the Activity's content frame but position it at the wrapper's screen
|
|
227
|
-
// coordinates so it visually appears in the expected React Native layout position.
|
|
228
|
-
wrapper.isUsingWindowPositioning = true
|
|
229
|
-
|
|
230
|
-
val activity = wrapper.reactContext.currentActivity
|
|
231
|
-
if (activity == null) {
|
|
232
|
-
Log.e(TAG, "No activity for subview-as-overlay; falling back to direct addView")
|
|
233
|
-
wrapper.isUsingWindowPositioning = false
|
|
234
|
-
wrapper.addView(adView)
|
|
235
|
-
return
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
val contentFrame = activity.window.decorView.findViewById<FrameLayout>(android.R.id.content)
|
|
239
|
-
if (contentFrame == null) {
|
|
240
|
-
Log.e(TAG, "No content frame for subview-as-overlay; falling back to direct addView")
|
|
241
|
-
wrapper.isUsingWindowPositioning = false
|
|
242
|
-
wrapper.addView(adView)
|
|
243
|
-
return
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
val isMREC = (wrapper.adType ?: "BANNER").uppercase() == "MREC"
|
|
247
|
-
val density = wrapper.context.resources.displayMetrics.density
|
|
248
|
-
val isTablet = wrapper.context.resources.configuration.smallestScreenWidthDp >= 600
|
|
249
|
-
val adWidthPx = ((if (isMREC) 300 else if (isTablet) 728 else 320) * density).toInt()
|
|
250
|
-
val adHeightPx = ((if (isMREC) 250 else if (isTablet) 90 else 50) * density).toInt()
|
|
251
|
-
|
|
252
|
-
val layoutParams = FrameLayout.LayoutParams(adWidthPx, adHeightPx).apply {
|
|
253
|
-
gravity = Gravity.TOP or Gravity.START
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
contentFrame.addView(adView, layoutParams)
|
|
257
|
-
adView.visibility = View.VISIBLE
|
|
258
|
-
|
|
259
|
-
// Position the ad at the wrapper's screen coordinates, updating on layout changes
|
|
260
|
-
fun updateAdPosition() {
|
|
261
|
-
if (wrapper.isDestroyed) return
|
|
262
|
-
val loc = IntArray(2)
|
|
263
|
-
wrapper.getLocationInWindow(loc)
|
|
264
|
-
val centerX = loc[0] + wrapper.width / 2 - adWidthPx / 2
|
|
265
|
-
val centerY = loc[1] + wrapper.height / 2 - adHeightPx / 2
|
|
266
|
-
layoutParams.leftMargin = centerX
|
|
267
|
-
layoutParams.topMargin = centerY
|
|
268
|
-
adView.layoutParams = layoutParams
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
wrapper.addOnLayoutChangeListener { _, _, _, _, _, _, _, _, _ ->
|
|
272
|
-
wrapper.postDelayed(::updateAdPosition, 100)
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
// Initial position after Yoga computes layout
|
|
276
|
-
wrapper.postDelayed(::updateAdPosition, 500)
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
private fun addAdToWindow(wrapper: CloudXBannerViewWrapper, adView: CloudXAdView, position: AdViewPosition, isMREC: Boolean) {
|
|
280
|
-
wrapper.isUsingWindowPositioning = true
|
|
281
|
-
|
|
282
|
-
val activity = wrapper.reactContext.currentActivity
|
|
283
|
-
if (activity == null) {
|
|
284
|
-
Log.e(TAG, "No activity found for window positioning, falling back to React Native layout")
|
|
285
|
-
addAdAsSubview(wrapper, adView)
|
|
286
|
-
return
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
val decorView = activity.window.decorView as? ViewGroup
|
|
290
|
-
if (decorView == null) {
|
|
291
|
-
Log.e(TAG, "No decor view found, falling back to React Native layout")
|
|
292
|
-
addAdAsSubview(wrapper, adView)
|
|
293
|
-
return
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
val contentFrame = decorView.findViewById<FrameLayout>(android.R.id.content)
|
|
297
|
-
if (contentFrame == null) {
|
|
298
|
-
Log.e(TAG, "No content frame found, falling back to React Native layout")
|
|
299
|
-
addAdAsSubview(wrapper, adView)
|
|
300
|
-
return
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
val density = wrapper.context.resources.displayMetrics.density
|
|
304
|
-
val isTablet = wrapper.context.resources.configuration.smallestScreenWidthDp >= 600
|
|
305
|
-
val bannerWidthPx = ((if (isMREC) 300 else if (isTablet) 728 else 320) * density).toInt()
|
|
306
|
-
val bannerHeightPx = ((if (isMREC) 250 else if (isTablet) 90 else 50) * density).toInt()
|
|
307
|
-
|
|
308
|
-
// Safe area insets (matches iOS safeAreaInsets behavior)
|
|
309
|
-
var insetTop = 0
|
|
310
|
-
var insetBottom = 0
|
|
311
|
-
var insetLeft = 0
|
|
312
|
-
var insetRight = 0
|
|
313
|
-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
|
314
|
-
val windowInsets = decorView.rootWindowInsets
|
|
315
|
-
if (windowInsets != null) {
|
|
316
|
-
val systemBars = windowInsets.getInsets(WindowInsets.Type.systemBars())
|
|
317
|
-
insetTop = systemBars.top
|
|
318
|
-
insetBottom = systemBars.bottom
|
|
319
|
-
insetLeft = systemBars.left
|
|
320
|
-
insetRight = systemBars.right
|
|
321
|
-
}
|
|
322
|
-
} else {
|
|
323
|
-
@Suppress("DEPRECATION")
|
|
324
|
-
decorView.rootWindowInsets?.let { insets ->
|
|
325
|
-
insetTop = insets.systemWindowInsetTop
|
|
326
|
-
insetBottom = insets.systemWindowInsetBottom
|
|
327
|
-
insetLeft = insets.systemWindowInsetLeft
|
|
328
|
-
insetRight = insets.systemWindowInsetRight
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
val gravity = when (position) {
|
|
333
|
-
AdViewPosition.TOP_LEFT -> Gravity.TOP or Gravity.START
|
|
334
|
-
AdViewPosition.TOP_CENTER -> Gravity.TOP or Gravity.CENTER_HORIZONTAL
|
|
335
|
-
AdViewPosition.TOP_RIGHT -> Gravity.TOP or Gravity.END
|
|
336
|
-
AdViewPosition.CENTER_LEFT -> Gravity.CENTER_VERTICAL or Gravity.START
|
|
337
|
-
AdViewPosition.CENTERED -> Gravity.CENTER
|
|
338
|
-
AdViewPosition.CENTER_RIGHT -> Gravity.CENTER_VERTICAL or Gravity.END
|
|
339
|
-
AdViewPosition.BOTTOM_LEFT -> Gravity.BOTTOM or Gravity.START
|
|
340
|
-
AdViewPosition.BOTTOM_CENTER -> Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL
|
|
341
|
-
AdViewPosition.BOTTOM_RIGHT -> Gravity.BOTTOM or Gravity.END
|
|
342
|
-
else -> Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
val marginTop = when (position) {
|
|
346
|
-
AdViewPosition.TOP_LEFT, AdViewPosition.TOP_CENTER, AdViewPosition.TOP_RIGHT -> insetTop
|
|
347
|
-
else -> 0
|
|
348
|
-
}
|
|
349
|
-
val marginBottom = when (position) {
|
|
350
|
-
AdViewPosition.BOTTOM_LEFT, AdViewPosition.BOTTOM_CENTER, AdViewPosition.BOTTOM_RIGHT -> insetBottom
|
|
351
|
-
else -> 0
|
|
352
|
-
}
|
|
353
|
-
val marginLeft = when (position) {
|
|
354
|
-
AdViewPosition.TOP_LEFT, AdViewPosition.CENTER_LEFT, AdViewPosition.BOTTOM_LEFT -> insetLeft
|
|
355
|
-
else -> 0
|
|
356
|
-
}
|
|
357
|
-
val marginRight = when (position) {
|
|
358
|
-
AdViewPosition.TOP_RIGHT, AdViewPosition.CENTER_RIGHT, AdViewPosition.BOTTOM_RIGHT -> insetRight
|
|
359
|
-
else -> 0
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
val layoutParams = FrameLayout.LayoutParams(bannerWidthPx, bannerHeightPx).apply {
|
|
363
|
-
this.gravity = gravity
|
|
364
|
-
setMargins(marginLeft, marginTop, marginRight, marginBottom)
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
contentFrame.addView(adView, layoutParams)
|
|
368
|
-
adView.visibility = View.VISIBLE
|
|
369
|
-
adView.bringToFront()
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
private fun serializeAdInfo(cloudXAd: CloudXAd, wrapper: CloudXBannerViewWrapper): WritableMap {
|
|
373
|
-
val map = Arguments.createMap()
|
|
374
|
-
map.putString("adUnitId", cloudXAd.adUnitId ?: wrapper.adId ?: "")
|
|
375
|
-
val adFormat = if ((wrapper.adType ?: "BANNER").uppercase() == "MREC") "MREC" else "BANNER"
|
|
376
|
-
map.putString("adFormat", adFormat)
|
|
377
|
-
map.putString("networkName", cloudXAd.networkName ?: "")
|
|
378
|
-
map.putString("networkPlacement", cloudXAd.networkPlacement ?: "")
|
|
379
|
-
map.putString("placement", cloudXAd.placement ?: wrapper.placement ?: "")
|
|
380
|
-
map.putDouble("revenue", cloudXAd.revenue)
|
|
381
|
-
return map
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
private fun serializeError(adUnitId: String, cloudXError: CloudXError): WritableMap {
|
|
385
|
-
val map = Arguments.createMap()
|
|
386
|
-
map.putString("adUnitId", adUnitId)
|
|
387
|
-
map.putInt("code", cloudXError.code.code)
|
|
388
|
-
map.putString("message", cloudXError.message ?: "Unknown error")
|
|
389
|
-
return map
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
private fun sendViewEvent(wrapper: CloudXBannerViewWrapper, eventName: String, data: WritableMap) {
|
|
393
|
-
val surfaceId = UIManagerHelper.getSurfaceId(wrapper)
|
|
394
|
-
val dispatcher = UIManagerHelper.getEventDispatcherForReactTag(wrapper.reactContext, wrapper.id)
|
|
395
|
-
if (dispatcher == null) {
|
|
396
|
-
Log.e(TAG, "Event dispatcher is null for event '$eventName' (viewId=${wrapper.id}, surfaceId=$surfaceId) — event will be lost")
|
|
397
|
-
return
|
|
398
|
-
}
|
|
399
|
-
dispatcher.dispatchEvent(CloudXAdViewEvent(surfaceId, wrapper.id, eventName, data))
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
private fun setupListeners(wrapper: CloudXBannerViewWrapper, adView: CloudXAdView, adId: String) {
|
|
403
|
-
adView.listener = object : CloudXAdViewListener {
|
|
404
|
-
override fun onAdLoaded(cloudXAd: CloudXAd) {
|
|
405
|
-
sendViewEvent(wrapper, "onAdLoaded", serializeAdInfo(cloudXAd, wrapper))
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
override fun onAdLoadFailed(adUnitId: String, cloudXError: CloudXError) {
|
|
409
|
-
sendViewEvent(wrapper, "onAdLoadFailed", serializeError(adUnitId, cloudXError))
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
override fun onAdClicked(cloudXAd: CloudXAd) {
|
|
413
|
-
sendViewEvent(wrapper, "onAdClicked", serializeAdInfo(cloudXAd, wrapper))
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
override fun onAdExpanded(cloudXAd: CloudXAd) {
|
|
417
|
-
sendViewEvent(wrapper, "onAdExpanded", serializeAdInfo(cloudXAd, wrapper))
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
override fun onAdCollapsed(cloudXAd: CloudXAd) {
|
|
421
|
-
sendViewEvent(wrapper, "onAdCollapsed", serializeAdInfo(cloudXAd, wrapper))
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
adView.revenueListener = object : CloudXAdRevenueListener {
|
|
426
|
-
override fun onAdRevenuePaid(cloudXAd: CloudXAd) {
|
|
427
|
-
sendViewEvent(wrapper, "onAdRevenuePaid", serializeAdInfo(cloudXAd, wrapper))
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
fun receiveCommand(view: CloudXBannerViewWrapper, commandId: String, args: com.facebook.react.bridge.ReadableArray?) {
|
|
433
|
-
when (commandId) {
|
|
434
|
-
"loadAd" -> loadAd(view)
|
|
435
|
-
"destroy" -> destroy(view)
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
fun loadAd(view: CloudXBannerViewWrapper) {
|
|
440
|
-
view.cloudXAdView?.load()
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
fun destroy(view: CloudXBannerViewWrapper) {
|
|
444
|
-
onDropViewInstance(view)
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
fun getExportedCustomDirectEventTypeConstants(): Map<String, Any> {
|
|
448
|
-
return MapBuilder.builder<String, Any>()
|
|
449
|
-
.put("onAdLoaded", MapBuilder.of("registrationName", "onAdLoaded"))
|
|
450
|
-
.put("onAdLoadFailed", MapBuilder.of("registrationName", "onAdLoadFailed"))
|
|
451
|
-
.put("onAdClicked", MapBuilder.of("registrationName", "onAdClicked"))
|
|
452
|
-
.put("onAdExpanded", MapBuilder.of("registrationName", "onAdExpanded"))
|
|
453
|
-
.put("onAdCollapsed", MapBuilder.of("registrationName", "onAdCollapsed"))
|
|
454
|
-
.put("onAdRevenuePaid", MapBuilder.of("registrationName", "onAdRevenuePaid"))
|
|
455
|
-
.build()
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
fun onDropViewInstance(view: CloudXBannerViewWrapper) {
|
|
459
|
-
view.isDestroyed = true
|
|
460
|
-
view.cloudXAdView?.let { adView ->
|
|
461
|
-
adView.listener = null
|
|
462
|
-
adView.revenueListener = null
|
|
463
|
-
adView.stopAutoRefresh()
|
|
464
|
-
if (view.isUsingWindowPositioning) {
|
|
465
|
-
(adView.parent as? ViewGroup)?.removeView(adView)
|
|
466
|
-
}
|
|
467
|
-
adView.destroy()
|
|
468
|
-
}
|
|
469
|
-
view.cloudXAdView = null
|
|
470
|
-
}
|
|
471
|
-
}
|
|
472
|
-
|