cloudx-react-native 2.0.0-beta.1 → 2.0.0
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/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
|
@@ -0,0 +1,694 @@
|
|
|
1
|
+
package com.cloudxreactnative
|
|
2
|
+
|
|
3
|
+
import android.app.Activity
|
|
4
|
+
import android.graphics.Color
|
|
5
|
+
import android.util.Log
|
|
6
|
+
import android.view.Gravity
|
|
7
|
+
import android.view.OrientationEventListener
|
|
8
|
+
import android.view.View
|
|
9
|
+
import android.view.ViewGroup
|
|
10
|
+
import android.widget.LinearLayout
|
|
11
|
+
import android.widget.RelativeLayout
|
|
12
|
+
import com.facebook.react.bridge.Arguments
|
|
13
|
+
import com.facebook.react.bridge.LifecycleEventListener
|
|
14
|
+
import com.facebook.react.bridge.Promise
|
|
15
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
16
|
+
import com.facebook.react.bridge.WritableMap
|
|
17
|
+
import com.facebook.react.modules.core.DeviceEventManagerModule
|
|
18
|
+
import io.cloudx.sdk.CloudX
|
|
19
|
+
import io.cloudx.sdk.CloudXAd
|
|
20
|
+
import io.cloudx.sdk.CloudXAdFormat
|
|
21
|
+
import io.cloudx.sdk.CloudXAdRevenueListener
|
|
22
|
+
import io.cloudx.sdk.CloudXAdView as SdkAdView
|
|
23
|
+
import io.cloudx.sdk.CloudXAdViewListener
|
|
24
|
+
import io.cloudx.sdk.CloudXError
|
|
25
|
+
import io.cloudx.sdk.CloudXInitializationConfiguration
|
|
26
|
+
import io.cloudx.sdk.CloudXInitializationListener
|
|
27
|
+
import io.cloudx.sdk.CloudXInterstitialAd
|
|
28
|
+
import io.cloudx.sdk.CloudXInterstitialListener
|
|
29
|
+
import io.cloudx.sdk.CloudXLogLevel
|
|
30
|
+
import io.cloudx.sdk.CloudXReward
|
|
31
|
+
import io.cloudx.sdk.CloudXRewardedAd
|
|
32
|
+
import io.cloudx.sdk.CloudXRewardedListener
|
|
33
|
+
import io.cloudx.sdk.CloudXSdkConfiguration
|
|
34
|
+
import java.util.concurrent.ConcurrentHashMap
|
|
35
|
+
|
|
36
|
+
class CloudXModuleImpl(private val reactApplicationContext: ReactApplicationContext) : LifecycleEventListener {
|
|
37
|
+
|
|
38
|
+
init {
|
|
39
|
+
reactApplicationContext.addLifecycleEventListener(this)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
private val interstitials = ConcurrentHashMap<String, CloudXInterstitialAd>()
|
|
43
|
+
private val rewardedAds = ConcurrentHashMap<String, CloudXRewardedAd>()
|
|
44
|
+
private val adViews = ConcurrentHashMap<String, SdkAdView>()
|
|
45
|
+
private val adViewAdFormats = ConcurrentHashMap<String, CloudXAdFormat>()
|
|
46
|
+
private val adViewPositions = ConcurrentHashMap<String, String>()
|
|
47
|
+
private val adViewOffsetsDp = ConcurrentHashMap<String, Pair<Float, Float>>()
|
|
48
|
+
private val adUnitIdsToShowAfterCreate = ConcurrentHashMap.newKeySet<String>()
|
|
49
|
+
// Workaround for React Native bug where getCurrentActivity() returns null:
|
|
50
|
+
// https://github.com/facebook/react-native/issues/18345
|
|
51
|
+
private var currentActivity: Activity? = null
|
|
52
|
+
private var windowManager: android.view.WindowManager? = null
|
|
53
|
+
private var lastRotation: Int = -1
|
|
54
|
+
|
|
55
|
+
private val DEFAULT_AD_VIEW_OFFSET_DP = Pair(0f, 0f)
|
|
56
|
+
|
|
57
|
+
companion object {
|
|
58
|
+
private const val TAG = "CloudX"
|
|
59
|
+
const val MODULE_NAME = "CloudX"
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// =========================================================================
|
|
63
|
+
// Activity Helper
|
|
64
|
+
// =========================================================================
|
|
65
|
+
|
|
66
|
+
private fun maybeGetCurrentActivity(): Activity? {
|
|
67
|
+
if (reactApplicationContext.hasCurrentActivity()) {
|
|
68
|
+
currentActivity = reactApplicationContext.currentActivity
|
|
69
|
+
}
|
|
70
|
+
return currentActivity
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// =========================================================================
|
|
74
|
+
// Initialization
|
|
75
|
+
// =========================================================================
|
|
76
|
+
|
|
77
|
+
fun isInitialized(promise: Promise) {
|
|
78
|
+
promise.resolve(CloudX.isInitialized())
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
fun initialize(pluginVersion: String, appKey: String, promise: Promise) {
|
|
82
|
+
val config = CloudXInitializationConfiguration.builder(appKey)
|
|
83
|
+
.setPluginVersion(pluginVersion)
|
|
84
|
+
.build()
|
|
85
|
+
|
|
86
|
+
CloudX.initialize(config, object : CloudXInitializationListener {
|
|
87
|
+
override fun onInitialized(configuration: CloudXSdkConfiguration) {
|
|
88
|
+
setupOrientationListener()
|
|
89
|
+
val result = Arguments.createMap()
|
|
90
|
+
result.putBoolean("success", true)
|
|
91
|
+
result.putString("message", "SDK initialized successfully")
|
|
92
|
+
promise.resolve(result)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
override fun onInitializationFailed(cloudXError: CloudXError) {
|
|
96
|
+
Log.e(TAG, "CloudX SDK initialization failed: ${cloudXError.message}")
|
|
97
|
+
promise.reject(cloudXError.code.name, cloudXError.message, null)
|
|
98
|
+
}
|
|
99
|
+
})
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
fun isTablet(promise: Promise) {
|
|
103
|
+
val isTablet = reactApplicationContext.resources.configuration.smallestScreenWidthDp >= 600
|
|
104
|
+
promise.resolve(isTablet)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
fun getVersion(promise: Promise) {
|
|
108
|
+
promise.resolve(CloudX.getVersion())
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// =========================================================================
|
|
112
|
+
// Configuration
|
|
113
|
+
// =========================================================================
|
|
114
|
+
|
|
115
|
+
fun setMinLogLevel(level: String) {
|
|
116
|
+
val logLevel = when (level.lowercase()) {
|
|
117
|
+
"verbose" -> CloudXLogLevel.VERBOSE
|
|
118
|
+
"debug" -> CloudXLogLevel.DEBUG
|
|
119
|
+
"info" -> CloudXLogLevel.INFO
|
|
120
|
+
"warn" -> CloudXLogLevel.WARN
|
|
121
|
+
"error" -> CloudXLogLevel.ERROR
|
|
122
|
+
"none" -> CloudXLogLevel.NONE
|
|
123
|
+
else -> CloudXLogLevel.INFO
|
|
124
|
+
}
|
|
125
|
+
CloudX.setMinLogLevel(logLevel)
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
fun setVisualDebuggingEnabled(enabled: Boolean) {
|
|
129
|
+
// Visual debugging is iOS-only; no-op on Android
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// =========================================================================
|
|
133
|
+
// User Targeting
|
|
134
|
+
// =========================================================================
|
|
135
|
+
|
|
136
|
+
fun setHashedUserID(hashedUserID: String) {
|
|
137
|
+
CloudX.setHashedUserId(hashedUserID)
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
fun setUserKeyValue(key: String, value: String) {
|
|
141
|
+
CloudX.setUserKeyValue(key, value)
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
fun setAppKeyValue(key: String, value: String) {
|
|
145
|
+
CloudX.setAppKeyValue(key, value)
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
fun clearAllKeyValues() {
|
|
149
|
+
CloudX.clearAllKeyValues()
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// =========================================================================
|
|
153
|
+
// Banner (Programmatic)
|
|
154
|
+
// =========================================================================
|
|
155
|
+
|
|
156
|
+
fun createBanner(adUnitId: String, position: String) = createAdView(adUnitId, CloudXAdFormat.BANNER, position, 0.0, 0.0)
|
|
157
|
+
fun createBannerWithOffsets(adUnitId: String, position: String, xOffset: Double, yOffset: Double) = createAdView(adUnitId, CloudXAdFormat.BANNER, position, xOffset, yOffset)
|
|
158
|
+
fun setBannerBackgroundColor(adUnitId: String, hexColorString: String) = setAdViewBackgroundColor(adUnitId, CloudXAdFormat.BANNER, hexColorString)
|
|
159
|
+
fun setBannerPlacement(adUnitId: String, placement: String?) = setAdViewPlacement(adUnitId, CloudXAdFormat.BANNER, placement)
|
|
160
|
+
fun setBannerCustomData(adUnitId: String, customData: String?) = setAdViewCustomData(adUnitId, CloudXAdFormat.BANNER, customData)
|
|
161
|
+
fun updateBannerPosition(adUnitId: String, position: String) = updateAdViewPosition(adUnitId, CloudXAdFormat.BANNER, position, adViewOffsetsDp[adUnitId] ?: DEFAULT_AD_VIEW_OFFSET_DP)
|
|
162
|
+
fun updateBannerOffsets(adUnitId: String, xOffset: Double, yOffset: Double) = updateAdViewPosition(adUnitId, CloudXAdFormat.BANNER, adViewPositions[adUnitId], Pair(xOffset.toFloat(), yOffset.toFloat()))
|
|
163
|
+
fun startBannerAutoRefresh(adUnitId: String) = startAdViewAutoRefresh(adUnitId, CloudXAdFormat.BANNER)
|
|
164
|
+
fun stopBannerAutoRefresh(adUnitId: String) = stopAdViewAutoRefresh(adUnitId, CloudXAdFormat.BANNER)
|
|
165
|
+
fun showBanner(adUnitId: String) = showAdView(adUnitId, CloudXAdFormat.BANNER)
|
|
166
|
+
fun hideBanner(adUnitId: String) = hideAdView(adUnitId, CloudXAdFormat.BANNER)
|
|
167
|
+
fun destroyBanner(adUnitId: String) = destroyAdView(adUnitId, CloudXAdFormat.BANNER)
|
|
168
|
+
|
|
169
|
+
// =========================================================================
|
|
170
|
+
// MREC (Programmatic)
|
|
171
|
+
// =========================================================================
|
|
172
|
+
|
|
173
|
+
fun createMREC(adUnitId: String, position: String) = createAdView(adUnitId, CloudXAdFormat.MREC, position, 0.0, 0.0)
|
|
174
|
+
fun createMRECWithOffsets(adUnitId: String, position: String, xOffset: Double, yOffset: Double) = createAdView(adUnitId, CloudXAdFormat.MREC, position, xOffset, yOffset)
|
|
175
|
+
fun setMRECBackgroundColor(adUnitId: String, hexColorString: String) = setAdViewBackgroundColor(adUnitId, CloudXAdFormat.MREC, hexColorString)
|
|
176
|
+
fun setMRECPlacement(adUnitId: String, placement: String?) = setAdViewPlacement(adUnitId, CloudXAdFormat.MREC, placement)
|
|
177
|
+
fun setMRECCustomData(adUnitId: String, customData: String?) = setAdViewCustomData(adUnitId, CloudXAdFormat.MREC, customData)
|
|
178
|
+
fun updateMRECPosition(adUnitId: String, position: String) = updateAdViewPosition(adUnitId, CloudXAdFormat.MREC, position, adViewOffsetsDp[adUnitId] ?: DEFAULT_AD_VIEW_OFFSET_DP)
|
|
179
|
+
fun updateMRECOffsets(adUnitId: String, xOffset: Double, yOffset: Double) = updateAdViewPosition(adUnitId, CloudXAdFormat.MREC, adViewPositions[adUnitId], Pair(xOffset.toFloat(), yOffset.toFloat()))
|
|
180
|
+
fun startMRECAutoRefresh(adUnitId: String) = startAdViewAutoRefresh(adUnitId, CloudXAdFormat.MREC)
|
|
181
|
+
fun stopMRECAutoRefresh(adUnitId: String) = stopAdViewAutoRefresh(adUnitId, CloudXAdFormat.MREC)
|
|
182
|
+
fun showMREC(adUnitId: String) = showAdView(adUnitId, CloudXAdFormat.MREC)
|
|
183
|
+
fun hideMREC(adUnitId: String) = hideAdView(adUnitId, CloudXAdFormat.MREC)
|
|
184
|
+
fun destroyMREC(adUnitId: String) = destroyAdView(adUnitId, CloudXAdFormat.MREC)
|
|
185
|
+
|
|
186
|
+
// =========================================================================
|
|
187
|
+
// Interstitial
|
|
188
|
+
// =========================================================================
|
|
189
|
+
|
|
190
|
+
fun loadInterstitial(adUnitId: String) {
|
|
191
|
+
retrieveInterstitial(adUnitId).load()
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
fun isInterstitialReady(adUnitId: String, promise: Promise) {
|
|
195
|
+
promise.resolve(retrieveInterstitial(adUnitId).isAdReady)
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
fun showInterstitial(adUnitId: String, placement: String?, customData: String?) {
|
|
199
|
+
val interstitial = retrieveInterstitial(adUnitId)
|
|
200
|
+
val activity = maybeGetCurrentActivity()
|
|
201
|
+
if (activity == null) {
|
|
202
|
+
Log.e(TAG, "showInterstitial: no activity available")
|
|
203
|
+
return
|
|
204
|
+
}
|
|
205
|
+
interstitial.show(activity, placement, customData)
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
fun destroyInterstitial(adUnitId: String) {
|
|
209
|
+
interstitials.remove(adUnitId)?.let {
|
|
210
|
+
it.listener = null
|
|
211
|
+
it.revenueListener = null
|
|
212
|
+
it.destroy()
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// =========================================================================
|
|
217
|
+
// Rewarded
|
|
218
|
+
// =========================================================================
|
|
219
|
+
|
|
220
|
+
fun loadRewarded(adUnitId: String) {
|
|
221
|
+
retrieveRewarded(adUnitId).load()
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
fun isRewardedReady(adUnitId: String, promise: Promise) {
|
|
225
|
+
promise.resolve(retrieveRewarded(adUnitId).isAdReady)
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
fun showRewarded(adUnitId: String, placement: String?, customData: String?) {
|
|
229
|
+
val rewarded = retrieveRewarded(adUnitId)
|
|
230
|
+
val activity = maybeGetCurrentActivity()
|
|
231
|
+
if (activity == null) {
|
|
232
|
+
Log.e(TAG, "showRewarded: no activity available")
|
|
233
|
+
return
|
|
234
|
+
}
|
|
235
|
+
rewarded.show(activity, placement, customData)
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
fun destroyRewarded(adUnitId: String) {
|
|
239
|
+
rewardedAds.remove(adUnitId)?.let {
|
|
240
|
+
it.listener = null
|
|
241
|
+
it.revenueListener = null
|
|
242
|
+
it.destroy()
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// =========================================================================
|
|
247
|
+
// Listener Factories
|
|
248
|
+
// =========================================================================
|
|
249
|
+
|
|
250
|
+
private fun createAdViewListener(adUnitId: String, adFormat: CloudXAdFormat): CloudXAdViewListener {
|
|
251
|
+
val isMrec = adFormat == CloudXAdFormat.MREC
|
|
252
|
+
val loadedEvent = if (isMrec) CloudXAdEvents.ON_MREC_AD_LOADED_EVENT else CloudXAdEvents.ON_BANNER_AD_LOADED_EVENT
|
|
253
|
+
val loadFailedEvent = if (isMrec) CloudXAdEvents.ON_MREC_AD_LOAD_FAILED_EVENT else CloudXAdEvents.ON_BANNER_AD_LOAD_FAILED_EVENT
|
|
254
|
+
val clickedEvent = if (isMrec) CloudXAdEvents.ON_MREC_AD_CLICKED_EVENT else CloudXAdEvents.ON_BANNER_AD_CLICKED_EVENT
|
|
255
|
+
val expandedEvent = if (isMrec) CloudXAdEvents.ON_MREC_AD_EXPANDED_EVENT else CloudXAdEvents.ON_BANNER_AD_EXPANDED_EVENT
|
|
256
|
+
val collapsedEvent = if (isMrec) CloudXAdEvents.ON_MREC_AD_COLLAPSED_EVENT else CloudXAdEvents.ON_BANNER_AD_COLLAPSED_EVENT
|
|
257
|
+
|
|
258
|
+
return object : CloudXAdViewListener {
|
|
259
|
+
override fun onAdLoaded(cloudXAd: CloudXAd) {
|
|
260
|
+
positionAdView(adUnitId, adFormat)
|
|
261
|
+
|
|
262
|
+
val adView = retrieveAdView(adUnitId, adFormat)
|
|
263
|
+
if (adView != null && adView.visibility != View.VISIBLE) {
|
|
264
|
+
adView.stopAutoRefresh()
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
sendReactNativeEvent(loadedEvent, getAdInfo(cloudXAd))
|
|
268
|
+
}
|
|
269
|
+
override fun onAdLoadFailed(failedAdUnitId: String, cloudXError: CloudXError) {
|
|
270
|
+
sendReactNativeEvent(loadFailedEvent, getAdLoadFailedInfo(failedAdUnitId, cloudXError))
|
|
271
|
+
}
|
|
272
|
+
override fun onAdClicked(cloudXAd: CloudXAd) {
|
|
273
|
+
sendReactNativeEvent(clickedEvent, getAdInfo(cloudXAd))
|
|
274
|
+
}
|
|
275
|
+
override fun onAdExpanded(cloudXAd: CloudXAd) {
|
|
276
|
+
sendReactNativeEvent(expandedEvent, getAdInfo(cloudXAd))
|
|
277
|
+
}
|
|
278
|
+
override fun onAdCollapsed(cloudXAd: CloudXAd) {
|
|
279
|
+
sendReactNativeEvent(collapsedEvent, getAdInfo(cloudXAd))
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
private fun createAdViewRevenueListener(adUnitId: String, adFormat: CloudXAdFormat): CloudXAdRevenueListener {
|
|
285
|
+
val revenueEvent = if (adFormat == CloudXAdFormat.MREC) CloudXAdEvents.ON_MREC_AD_REVENUE_PAID else CloudXAdEvents.ON_BANNER_AD_REVENUE_PAID
|
|
286
|
+
return object : CloudXAdRevenueListener {
|
|
287
|
+
override fun onAdRevenuePaid(cloudXAd: CloudXAd) {
|
|
288
|
+
sendReactNativeEvent(revenueEvent, getAdInfo(cloudXAd))
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
private fun createInterstitialListener(adUnitId: String): CloudXInterstitialListener {
|
|
294
|
+
return object : CloudXInterstitialListener {
|
|
295
|
+
override fun onAdLoaded(cloudXAd: CloudXAd) {
|
|
296
|
+
sendReactNativeEvent(CloudXAdEvents.ON_INTERSTITIAL_LOADED_EVENT, getAdInfo(cloudXAd))
|
|
297
|
+
}
|
|
298
|
+
override fun onAdLoadFailed(failedAdUnitId: String, cloudXError: CloudXError) {
|
|
299
|
+
sendReactNativeEvent(CloudXAdEvents.ON_INTERSTITIAL_LOAD_FAILED_EVENT, getAdLoadFailedInfo(failedAdUnitId, cloudXError))
|
|
300
|
+
}
|
|
301
|
+
override fun onAdClicked(cloudXAd: CloudXAd) {
|
|
302
|
+
sendReactNativeEvent(CloudXAdEvents.ON_INTERSTITIAL_CLICKED_EVENT, getAdInfo(cloudXAd))
|
|
303
|
+
}
|
|
304
|
+
override fun onAdDisplayed(cloudXAd: CloudXAd) {
|
|
305
|
+
sendReactNativeEvent(CloudXAdEvents.ON_INTERSTITIAL_DISPLAYED_EVENT, getAdInfo(cloudXAd))
|
|
306
|
+
}
|
|
307
|
+
override fun onAdDisplayFailed(cloudXAd: CloudXAd, cloudXError: CloudXError) {
|
|
308
|
+
sendReactNativeEvent(CloudXAdEvents.ON_INTERSTITIAL_DISPLAY_FAILED_EVENT, getAdDisplayFailedInfo(cloudXAd, cloudXError))
|
|
309
|
+
}
|
|
310
|
+
override fun onAdHidden(cloudXAd: CloudXAd) {
|
|
311
|
+
sendReactNativeEvent(CloudXAdEvents.ON_INTERSTITIAL_HIDDEN_EVENT, getAdInfo(cloudXAd))
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
private fun createRewardedListener(adUnitId: String): CloudXRewardedListener {
|
|
317
|
+
return object : CloudXRewardedListener {
|
|
318
|
+
override fun onAdLoaded(cloudXAd: CloudXAd) {
|
|
319
|
+
sendReactNativeEvent(CloudXAdEvents.ON_REWARDED_AD_LOADED_EVENT, getAdInfo(cloudXAd))
|
|
320
|
+
}
|
|
321
|
+
override fun onAdLoadFailed(failedAdUnitId: String, cloudXError: CloudXError) {
|
|
322
|
+
sendReactNativeEvent(CloudXAdEvents.ON_REWARDED_AD_LOAD_FAILED_EVENT, getAdLoadFailedInfo(failedAdUnitId, cloudXError))
|
|
323
|
+
}
|
|
324
|
+
override fun onAdClicked(cloudXAd: CloudXAd) {
|
|
325
|
+
sendReactNativeEvent(CloudXAdEvents.ON_REWARDED_AD_CLICKED_EVENT, getAdInfo(cloudXAd))
|
|
326
|
+
}
|
|
327
|
+
override fun onAdDisplayed(cloudXAd: CloudXAd) {
|
|
328
|
+
sendReactNativeEvent(CloudXAdEvents.ON_REWARDED_AD_DISPLAYED_EVENT, getAdInfo(cloudXAd))
|
|
329
|
+
}
|
|
330
|
+
override fun onAdDisplayFailed(cloudXAd: CloudXAd, cloudXError: CloudXError) {
|
|
331
|
+
sendReactNativeEvent(CloudXAdEvents.ON_REWARDED_AD_DISPLAY_FAILED_EVENT, getAdDisplayFailedInfo(cloudXAd, cloudXError))
|
|
332
|
+
}
|
|
333
|
+
override fun onAdHidden(cloudXAd: CloudXAd) {
|
|
334
|
+
sendReactNativeEvent(CloudXAdEvents.ON_REWARDED_AD_HIDDEN_EVENT, getAdInfo(cloudXAd))
|
|
335
|
+
}
|
|
336
|
+
override fun onUserRewarded(cloudXAd: CloudXAd, reward: CloudXReward) {
|
|
337
|
+
val data = getAdInfo(cloudXAd)
|
|
338
|
+
data.putString("rewardLabel", reward.label)
|
|
339
|
+
data.putInt("rewardAmount", reward.amount)
|
|
340
|
+
sendReactNativeEvent(CloudXAdEvents.ON_REWARDED_AD_RECEIVED_REWARD_EVENT, data)
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
private fun createFullscreenRevenueListener(adUnitId: String, eventName: String): CloudXAdRevenueListener {
|
|
346
|
+
return object : CloudXAdRevenueListener {
|
|
347
|
+
override fun onAdRevenuePaid(cloudXAd: CloudXAd) {
|
|
348
|
+
sendReactNativeEvent(eventName, getAdInfo(cloudXAd))
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
// =========================================================================
|
|
354
|
+
// Ad View Helpers (shared by Banner and MREC)
|
|
355
|
+
// =========================================================================
|
|
356
|
+
|
|
357
|
+
private fun createAdView(adUnitId: String, adFormat: CloudXAdFormat, position: String, xOffset: Double, yOffset: Double) {
|
|
358
|
+
// Run on main thread to ensure there are no concurrency issues with other ad view methods
|
|
359
|
+
reactApplicationContext.runOnUiQueueThread {
|
|
360
|
+
val adView = retrieveAdView(adUnitId, adFormat, position, Pair(xOffset.toFloat(), yOffset.toFloat()))
|
|
361
|
+
?: return@runOnUiQueueThread
|
|
362
|
+
|
|
363
|
+
adView.visibility = View.GONE
|
|
364
|
+
|
|
365
|
+
if (adView.parent == null) {
|
|
366
|
+
maybeAttachToCurrentActivity(adView)
|
|
367
|
+
adViewAdFormats[adUnitId] = adFormat
|
|
368
|
+
positionAdView(adUnitId, adFormat)
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
adView.load()
|
|
372
|
+
|
|
373
|
+
// The publisher may have requested to show the ad view before it was created.
|
|
374
|
+
if (adUnitIdsToShowAfterCreate.contains(adUnitId)) {
|
|
375
|
+
showAdView(adUnitId, adFormat)
|
|
376
|
+
adUnitIdsToShowAfterCreate.remove(adUnitId)
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
private fun setAdViewPlacement(adUnitId: String, adFormat: CloudXAdFormat, placement: String?) {
|
|
382
|
+
reactApplicationContext.runOnUiQueueThread {
|
|
383
|
+
val adView = retrieveAdView(adUnitId, adFormat, "", DEFAULT_AD_VIEW_OFFSET_DP) ?: return@runOnUiQueueThread
|
|
384
|
+
adView.setPlacement(placement)
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
private fun setAdViewCustomData(adUnitId: String, adFormat: CloudXAdFormat, customData: String?) {
|
|
389
|
+
reactApplicationContext.runOnUiQueueThread {
|
|
390
|
+
val adView = retrieveAdView(adUnitId, adFormat, "", DEFAULT_AD_VIEW_OFFSET_DP) ?: return@runOnUiQueueThread
|
|
391
|
+
adView.setCustomData(customData)
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
private fun updateAdViewPosition(adUnitId: String, adFormat: CloudXAdFormat, position: String?, offsetsDp: Pair<Float, Float>) {
|
|
396
|
+
reactApplicationContext.runOnUiQueueThread {
|
|
397
|
+
val adView = retrieveAdView(adUnitId, adFormat) ?: return@runOnUiQueueThread
|
|
398
|
+
adViewPositions[adUnitId] = position ?: return@runOnUiQueueThread
|
|
399
|
+
adViewOffsetsDp[adUnitId] = offsetsDp
|
|
400
|
+
positionAdView(adUnitId, adFormat)
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
private fun showAdView(adUnitId: String, adFormat: CloudXAdFormat) {
|
|
405
|
+
reactApplicationContext.runOnUiQueueThread {
|
|
406
|
+
val adView = retrieveAdView(adUnitId, adFormat)
|
|
407
|
+
if (adView == null) {
|
|
408
|
+
adUnitIdsToShowAfterCreate.add(adUnitId)
|
|
409
|
+
return@runOnUiQueueThread
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
maybeAttachToCurrentActivity(adView)
|
|
413
|
+
adView.visibility = View.VISIBLE
|
|
414
|
+
adView.startAutoRefresh()
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
private fun hideAdView(adUnitId: String, adFormat: CloudXAdFormat) {
|
|
419
|
+
reactApplicationContext.runOnUiQueueThread {
|
|
420
|
+
adUnitIdsToShowAfterCreate.remove(adUnitId)
|
|
421
|
+
val adView = retrieveAdView(adUnitId, adFormat) ?: return@runOnUiQueueThread
|
|
422
|
+
adView.visibility = View.GONE
|
|
423
|
+
adView.stopAutoRefresh()
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
private fun destroyAdView(adUnitId: String, adFormat: CloudXAdFormat) {
|
|
428
|
+
reactApplicationContext.runOnUiQueueThread {
|
|
429
|
+
val adView = retrieveAdView(adUnitId, adFormat)
|
|
430
|
+
if (adView == null) return@runOnUiQueueThread
|
|
431
|
+
|
|
432
|
+
val parent = adView.parent
|
|
433
|
+
if (parent is ViewGroup) {
|
|
434
|
+
parent.removeView(adView)
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
adView.listener = null
|
|
438
|
+
adView.revenueListener = null
|
|
439
|
+
adView.destroy()
|
|
440
|
+
|
|
441
|
+
adViews.remove(adUnitId)
|
|
442
|
+
adViewAdFormats.remove(adUnitId)
|
|
443
|
+
adViewPositions.remove(adUnitId)
|
|
444
|
+
adViewOffsetsDp.remove(adUnitId)
|
|
445
|
+
adUnitIdsToShowAfterCreate.remove(adUnitId)
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
private fun setAdViewBackgroundColor(adUnitId: String, adFormat: CloudXAdFormat, hexColorString: String) {
|
|
450
|
+
reactApplicationContext.runOnUiQueueThread {
|
|
451
|
+
val adView = retrieveAdView(adUnitId, adFormat) ?: return@runOnUiQueueThread
|
|
452
|
+
try {
|
|
453
|
+
adView.setBackgroundColor(Color.parseColor(hexColorString))
|
|
454
|
+
} catch (e: IllegalArgumentException) {
|
|
455
|
+
Log.e(TAG, "setAdViewBackgroundColor: invalid color string \"$hexColorString\"", e)
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
private fun startAdViewAutoRefresh(adUnitId: String, adFormat: CloudXAdFormat) {
|
|
461
|
+
reactApplicationContext.runOnUiQueueThread { retrieveAdView(adUnitId, adFormat)?.startAutoRefresh() }
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
private fun stopAdViewAutoRefresh(adUnitId: String, adFormat: CloudXAdFormat) {
|
|
465
|
+
reactApplicationContext.runOnUiQueueThread { retrieveAdView(adUnitId, adFormat)?.stopAutoRefresh() }
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
// =========================================================================
|
|
469
|
+
// Ad View Positioning
|
|
470
|
+
// =========================================================================
|
|
471
|
+
|
|
472
|
+
private fun maybeAttachToCurrentActivity(adView: SdkAdView) {
|
|
473
|
+
if (adView.parent != null) return
|
|
474
|
+
|
|
475
|
+
val activity = maybeGetCurrentActivity()
|
|
476
|
+
if (activity == null) {
|
|
477
|
+
Log.e(TAG, "maybeAttachToCurrentActivity: no activity available")
|
|
478
|
+
return
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
val relativeLayout = RelativeLayout(reactApplicationContext)
|
|
482
|
+
relativeLayout.addView(adView)
|
|
483
|
+
|
|
484
|
+
activity.addContentView(
|
|
485
|
+
relativeLayout,
|
|
486
|
+
LinearLayout.LayoutParams(
|
|
487
|
+
LinearLayout.LayoutParams.MATCH_PARENT,
|
|
488
|
+
LinearLayout.LayoutParams.MATCH_PARENT
|
|
489
|
+
)
|
|
490
|
+
)
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
private fun retrieveInterstitial(adUnitId: String): CloudXInterstitialAd {
|
|
494
|
+
var interstitial = interstitials[adUnitId]
|
|
495
|
+
if (interstitial == null) {
|
|
496
|
+
interstitial = CloudX.createInterstitial(adUnitId)
|
|
497
|
+
interstitial.listener = createInterstitialListener(adUnitId)
|
|
498
|
+
interstitial.revenueListener = createFullscreenRevenueListener(adUnitId, CloudXAdEvents.ON_INTERSTITIAL_AD_REVENUE_PAID)
|
|
499
|
+
interstitials[adUnitId] = interstitial
|
|
500
|
+
}
|
|
501
|
+
return interstitial
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
private fun retrieveRewarded(adUnitId: String): CloudXRewardedAd {
|
|
505
|
+
var rewarded = rewardedAds[adUnitId]
|
|
506
|
+
if (rewarded == null) {
|
|
507
|
+
rewarded = CloudX.createRewarded(adUnitId)
|
|
508
|
+
rewarded.listener = createRewardedListener(adUnitId)
|
|
509
|
+
rewarded.revenueListener = createFullscreenRevenueListener(adUnitId, CloudXAdEvents.ON_REWARDED_AD_REVENUE_PAID)
|
|
510
|
+
rewardedAds[adUnitId] = rewarded
|
|
511
|
+
}
|
|
512
|
+
return rewarded
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
private fun retrieveAdView(adUnitId: String, adFormat: CloudXAdFormat): SdkAdView? {
|
|
516
|
+
return retrieveAdView(adUnitId, adFormat, null, DEFAULT_AD_VIEW_OFFSET_DP)
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
private fun retrieveAdView(adUnitId: String, adFormat: CloudXAdFormat, position: String?, offsetsDp: Pair<Float, Float>): SdkAdView? {
|
|
520
|
+
var adView = adViews[adUnitId]
|
|
521
|
+
if (adView == null && position != null) {
|
|
522
|
+
adView = if (adFormat == CloudXAdFormat.MREC) CloudX.createMREC(adUnitId) else CloudX.createBanner(adUnitId)
|
|
523
|
+
adView.listener = createAdViewListener(adUnitId, adFormat)
|
|
524
|
+
adView.revenueListener = createAdViewRevenueListener(adUnitId, adFormat)
|
|
525
|
+
adViews[adUnitId] = adView
|
|
526
|
+
adViewPositions[adUnitId] = position
|
|
527
|
+
adViewOffsetsDp[adUnitId] = offsetsDp
|
|
528
|
+
}
|
|
529
|
+
return adView
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
private fun positionAdView(adUnitId: String, adFormat: CloudXAdFormat) {
|
|
533
|
+
val adView = retrieveAdView(adUnitId, adFormat) ?: return
|
|
534
|
+
val relativeLayout = adView.parent as? RelativeLayout
|
|
535
|
+
if (relativeLayout == null) {
|
|
536
|
+
Log.e(TAG, "positionAdView: ad view has no parent layout")
|
|
537
|
+
return
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
val density = reactApplicationContext.resources.displayMetrics.density
|
|
541
|
+
val params = adView.layoutParams as RelativeLayout.LayoutParams
|
|
542
|
+
|
|
543
|
+
// Reset stale state before repositioning
|
|
544
|
+
adView.rotation = 0f
|
|
545
|
+
adView.translationX = 0f
|
|
546
|
+
adView.translationY = 0f
|
|
547
|
+
params.setMargins(0, 0, 0, 0)
|
|
548
|
+
|
|
549
|
+
val isMREC = adFormat == CloudXAdFormat.MREC
|
|
550
|
+
val isTablet = reactApplicationContext.resources.configuration.smallestScreenWidthDp >= 600
|
|
551
|
+
params.width = ((if (isMREC) 300 else if (isTablet) 728 else 320) * density).toInt()
|
|
552
|
+
params.height = ((if (isMREC) 250 else if (isTablet) 90 else 50) * density).toInt()
|
|
553
|
+
adView.layoutParams = params
|
|
554
|
+
|
|
555
|
+
val position = (adViewPositions[adUnitId] ?: "BOTTOM_CENTER").uppercase()
|
|
556
|
+
val offsetsDp = adViewOffsetsDp[adUnitId] ?: Pair(0f, 0f)
|
|
557
|
+
val offsetXPx = (offsetsDp.first * density).toInt()
|
|
558
|
+
val offsetYPx = (offsetsDp.second * density).toInt()
|
|
559
|
+
|
|
560
|
+
val gravity = when (position) {
|
|
561
|
+
"TOP_LEFT" -> Gravity.TOP or Gravity.START
|
|
562
|
+
"TOP_CENTER" -> Gravity.TOP or Gravity.CENTER_HORIZONTAL
|
|
563
|
+
"TOP_RIGHT" -> Gravity.TOP or Gravity.END
|
|
564
|
+
"CENTER_LEFT" -> Gravity.CENTER_VERTICAL or Gravity.START
|
|
565
|
+
"CENTERED" -> Gravity.CENTER
|
|
566
|
+
"CENTER_RIGHT" -> Gravity.CENTER_VERTICAL or Gravity.END
|
|
567
|
+
"BOTTOM_LEFT" -> Gravity.BOTTOM or Gravity.START
|
|
568
|
+
"BOTTOM_CENTER" -> Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL
|
|
569
|
+
"BOTTOM_RIGHT" -> Gravity.BOTTOM or Gravity.END
|
|
570
|
+
else -> Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
relativeLayout.gravity = gravity
|
|
574
|
+
relativeLayout.setPadding(0, 0, 0, 0)
|
|
575
|
+
|
|
576
|
+
// Apply offsets directionally based on which edges are active for the position.
|
|
577
|
+
// For edge-anchored axes, use margins (which push the view inward from the edge).
|
|
578
|
+
// For center-anchored axes, margins don't shift centered children, so use translation.
|
|
579
|
+
val isLeft = position.endsWith("LEFT")
|
|
580
|
+
val isRight = position.endsWith("RIGHT")
|
|
581
|
+
val isTop = position.startsWith("TOP")
|
|
582
|
+
val isBottom = position.startsWith("BOTTOM")
|
|
583
|
+
val isCenterHorizontal = !isLeft && !isRight // TOP_CENTER, BOTTOM_CENTER, CENTERED
|
|
584
|
+
val isCenterVertical = !isTop && !isBottom // CENTER_LEFT, CENTER_RIGHT, CENTERED
|
|
585
|
+
|
|
586
|
+
params.marginStart = if (isLeft) offsetXPx else 0
|
|
587
|
+
params.marginEnd = if (isRight) offsetXPx else 0
|
|
588
|
+
params.topMargin = if (isTop) offsetYPx else 0
|
|
589
|
+
params.bottomMargin = if (isBottom) offsetYPx else 0
|
|
590
|
+
adView.layoutParams = params
|
|
591
|
+
|
|
592
|
+
adView.translationX = if (isCenterHorizontal) offsetXPx.toFloat() else 0f
|
|
593
|
+
adView.translationY = if (isCenterVertical) offsetYPx.toFloat() else 0f
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
// =========================================================================
|
|
597
|
+
// Orientation Change Handler
|
|
598
|
+
// =========================================================================
|
|
599
|
+
|
|
600
|
+
private fun setupOrientationListener() {
|
|
601
|
+
if (windowManager != null) return
|
|
602
|
+
|
|
603
|
+
windowManager = reactApplicationContext.getSystemService(android.content.Context.WINDOW_SERVICE) as android.view.WindowManager
|
|
604
|
+
|
|
605
|
+
@Suppress("DEPRECATION")
|
|
606
|
+
lastRotation = windowManager!!.defaultDisplay.rotation
|
|
607
|
+
|
|
608
|
+
object : OrientationEventListener(reactApplicationContext) {
|
|
609
|
+
override fun onOrientationChanged(orientation: Int) {
|
|
610
|
+
@Suppress("DEPRECATION")
|
|
611
|
+
val newRotation = windowManager?.defaultDisplay?.rotation ?: return
|
|
612
|
+
if (newRotation != lastRotation) {
|
|
613
|
+
lastRotation = newRotation
|
|
614
|
+
for ((adUnitId, adFormat) in adViewAdFormats) {
|
|
615
|
+
positionAdView(adUnitId, adFormat)
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
}.enable()
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
// =========================================================================
|
|
623
|
+
// Ad Info
|
|
624
|
+
// =========================================================================
|
|
625
|
+
|
|
626
|
+
// =========================================================================
|
|
627
|
+
// Lifecycle
|
|
628
|
+
// =========================================================================
|
|
629
|
+
|
|
630
|
+
override fun onHostResume() {}
|
|
631
|
+
override fun onHostPause() {}
|
|
632
|
+
|
|
633
|
+
override fun onHostDestroy() {
|
|
634
|
+
// Make copy because destroyAdView() removes from adViews
|
|
635
|
+
val adViewsCopy = HashMap(adViewAdFormats)
|
|
636
|
+
for ((adUnitId, adFormat) in adViewsCopy) {
|
|
637
|
+
destroyAdView(adUnitId, adFormat)
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
for (interstitial in interstitials.values) {
|
|
641
|
+
interstitial.destroy()
|
|
642
|
+
}
|
|
643
|
+
interstitials.clear()
|
|
644
|
+
|
|
645
|
+
for (rewarded in rewardedAds.values) {
|
|
646
|
+
rewarded.destroy()
|
|
647
|
+
}
|
|
648
|
+
rewardedAds.clear()
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
// =========================================================================
|
|
652
|
+
// React Native Bridge
|
|
653
|
+
// =========================================================================
|
|
654
|
+
|
|
655
|
+
private fun sendReactNativeEvent(name: String, params: WritableMap) {
|
|
656
|
+
reactApplicationContext
|
|
657
|
+
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
658
|
+
.emit(name, params)
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
// =========================================================================
|
|
662
|
+
// Constants
|
|
663
|
+
// =========================================================================
|
|
664
|
+
|
|
665
|
+
fun getConstants(): MutableMap<String, Any> = mutableMapOf(
|
|
666
|
+
"ON_BANNER_AD_LOADED_EVENT" to CloudXAdEvents.ON_BANNER_AD_LOADED_EVENT,
|
|
667
|
+
"ON_BANNER_AD_LOAD_FAILED_EVENT" to CloudXAdEvents.ON_BANNER_AD_LOAD_FAILED_EVENT,
|
|
668
|
+
"ON_BANNER_AD_CLICKED_EVENT" to CloudXAdEvents.ON_BANNER_AD_CLICKED_EVENT,
|
|
669
|
+
"ON_BANNER_AD_EXPANDED_EVENT" to CloudXAdEvents.ON_BANNER_AD_EXPANDED_EVENT,
|
|
670
|
+
"ON_BANNER_AD_COLLAPSED_EVENT" to CloudXAdEvents.ON_BANNER_AD_COLLAPSED_EVENT,
|
|
671
|
+
"ON_BANNER_AD_REVENUE_PAID" to CloudXAdEvents.ON_BANNER_AD_REVENUE_PAID,
|
|
672
|
+
"ON_MREC_AD_LOADED_EVENT" to CloudXAdEvents.ON_MREC_AD_LOADED_EVENT,
|
|
673
|
+
"ON_MREC_AD_LOAD_FAILED_EVENT" to CloudXAdEvents.ON_MREC_AD_LOAD_FAILED_EVENT,
|
|
674
|
+
"ON_MREC_AD_CLICKED_EVENT" to CloudXAdEvents.ON_MREC_AD_CLICKED_EVENT,
|
|
675
|
+
"ON_MREC_AD_EXPANDED_EVENT" to CloudXAdEvents.ON_MREC_AD_EXPANDED_EVENT,
|
|
676
|
+
"ON_MREC_AD_COLLAPSED_EVENT" to CloudXAdEvents.ON_MREC_AD_COLLAPSED_EVENT,
|
|
677
|
+
"ON_MREC_AD_REVENUE_PAID" to CloudXAdEvents.ON_MREC_AD_REVENUE_PAID,
|
|
678
|
+
"ON_INTERSTITIAL_LOADED_EVENT" to CloudXAdEvents.ON_INTERSTITIAL_LOADED_EVENT,
|
|
679
|
+
"ON_INTERSTITIAL_LOAD_FAILED_EVENT" to CloudXAdEvents.ON_INTERSTITIAL_LOAD_FAILED_EVENT,
|
|
680
|
+
"ON_INTERSTITIAL_CLICKED_EVENT" to CloudXAdEvents.ON_INTERSTITIAL_CLICKED_EVENT,
|
|
681
|
+
"ON_INTERSTITIAL_DISPLAYED_EVENT" to CloudXAdEvents.ON_INTERSTITIAL_DISPLAYED_EVENT,
|
|
682
|
+
"ON_INTERSTITIAL_DISPLAY_FAILED_EVENT" to CloudXAdEvents.ON_INTERSTITIAL_DISPLAY_FAILED_EVENT,
|
|
683
|
+
"ON_INTERSTITIAL_HIDDEN_EVENT" to CloudXAdEvents.ON_INTERSTITIAL_HIDDEN_EVENT,
|
|
684
|
+
"ON_INTERSTITIAL_AD_REVENUE_PAID" to CloudXAdEvents.ON_INTERSTITIAL_AD_REVENUE_PAID,
|
|
685
|
+
"ON_REWARDED_AD_LOADED_EVENT" to CloudXAdEvents.ON_REWARDED_AD_LOADED_EVENT,
|
|
686
|
+
"ON_REWARDED_AD_LOAD_FAILED_EVENT" to CloudXAdEvents.ON_REWARDED_AD_LOAD_FAILED_EVENT,
|
|
687
|
+
"ON_REWARDED_AD_CLICKED_EVENT" to CloudXAdEvents.ON_REWARDED_AD_CLICKED_EVENT,
|
|
688
|
+
"ON_REWARDED_AD_DISPLAYED_EVENT" to CloudXAdEvents.ON_REWARDED_AD_DISPLAYED_EVENT,
|
|
689
|
+
"ON_REWARDED_AD_DISPLAY_FAILED_EVENT" to CloudXAdEvents.ON_REWARDED_AD_DISPLAY_FAILED_EVENT,
|
|
690
|
+
"ON_REWARDED_AD_HIDDEN_EVENT" to CloudXAdEvents.ON_REWARDED_AD_HIDDEN_EVENT,
|
|
691
|
+
"ON_REWARDED_AD_RECEIVED_REWARD_EVENT" to CloudXAdEvents.ON_REWARDED_AD_RECEIVED_REWARD_EVENT,
|
|
692
|
+
"ON_REWARDED_AD_REVENUE_PAID" to CloudXAdEvents.ON_REWARDED_AD_REVENUE_PAID,
|
|
693
|
+
)
|
|
694
|
+
}
|