react-native-daro 1.0.13 → 1.0.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (164) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +30 -30
  3. package/android/build.gradle +42 -59
  4. package/android/src/admob/java/com/daro/reactnative/DaroSdkBridge.kt +23 -0
  5. package/android/src/main/AndroidManifest.xml +1 -2
  6. package/android/src/main/java/com/{darom → daro/reactnative}/DaroMAdBannerViewManager.kt +4 -4
  7. package/android/src/main/java/com/{darom → daro/reactnative}/DaroMAdNativeViewManager.kt +4 -4
  8. package/android/src/main/java/com/{darom → daro/reactnative}/DaroMModule.kt +44 -45
  9. package/android/src/main/java/com/{darom → daro/reactnative}/DaroMPackage.kt +1 -1
  10. package/android/src/main/java/com/{darom → daro/reactnative}/constants/InternalDaroMBannerSize.kt +1 -1
  11. package/android/src/main/java/com/{darom → daro/reactnative}/event/DaroMEvent.kt +1 -1
  12. package/android/src/main/java/com/{darom → daro/reactnative}/impl/DaroMBannerViewModuleImpl.kt +2 -2
  13. package/android/src/main/java/com/{darom → daro/reactnative}/impl/DaroMInterstitialModuleImpl.kt +26 -26
  14. package/android/src/main/java/com/{darom → daro/reactnative}/impl/DaroMLightPopupModuleImpl.kt +30 -29
  15. package/android/src/main/java/com/{darom → daro/reactnative}/impl/DaroMRewardedAdModuleImpl.kt +27 -27
  16. package/android/src/main/java/com/{darom → daro/reactnative}/util/AdInfoUtil.kt +25 -1
  17. package/android/src/main/java/com/{darom → daro/reactnative}/util/EventEmitterUtil.kt +2 -2
  18. package/android/src/main/java/com/daro/reactnative/view/DaroMAdBannerViewContainer.kt +417 -0
  19. package/android/src/main/java/com/{darom → daro/reactnative}/view/DaroMAdNativeViewContainer.kt +4 -4
  20. package/app.plugin.js +1 -0
  21. package/ios/DaroMAdBannerViewManager.swift +1 -1
  22. package/ios/DaroMModule+AppOpen.swift +34 -31
  23. package/ios/DaroMModule+Interstitial.swift +29 -26
  24. package/ios/DaroMModule+LightPopup.swift +40 -33
  25. package/ios/DaroMModule+Rewarded.swift +35 -27
  26. package/ios/DaroMModule.mm +13 -13
  27. package/ios/DaroMModule.swift +20 -13
  28. package/ios/DaroMNativeAdViewManager.swift +1 -1
  29. package/ios/mediation/admob/DaroMediationDebugger.swift +11 -0
  30. package/ios/mediation/admob/DaroMediationTypes.swift +22 -0
  31. package/lib/commonjs/AdBannerView.js +6 -1
  32. package/lib/commonjs/AdBannerView.js.map +1 -1
  33. package/lib/commonjs/AppOpenAd.js +43 -17
  34. package/lib/commonjs/AppOpenAd.js.map +1 -1
  35. package/lib/commonjs/ErrorCode.js.map +1 -1
  36. package/lib/commonjs/EventEmitter.js.map +1 -1
  37. package/lib/commonjs/InterstitialAd.js +45 -17
  38. package/lib/commonjs/InterstitialAd.js.map +1 -1
  39. package/lib/commonjs/LightPopupAd.js +62 -43
  40. package/lib/commonjs/LightPopupAd.js.map +1 -1
  41. package/lib/commonjs/RewardedAd.js +44 -18
  42. package/lib/commonjs/RewardedAd.js.map +1 -1
  43. package/lib/commonjs/index.js +1 -1
  44. package/lib/commonjs/index.js.map +1 -1
  45. package/lib/commonjs/nativeAd/NativeAdView.js +5 -1
  46. package/lib/commonjs/nativeAd/NativeAdView.js.map +1 -1
  47. package/lib/commonjs/nativeAd/NativeAdViewComponents.js.map +1 -1
  48. package/lib/commonjs/nativeAd/NativeAdViewProvider.js.map +1 -1
  49. package/lib/commonjs/package.json +1 -0
  50. package/lib/module/AdBannerView.js +6 -1
  51. package/lib/module/AdBannerView.js.map +1 -1
  52. package/lib/module/AppOpenAd.js +43 -17
  53. package/lib/module/AppOpenAd.js.map +1 -1
  54. package/lib/module/ErrorCode.js.map +1 -1
  55. package/lib/module/EventEmitter.js.map +1 -1
  56. package/lib/module/InterstitialAd.js +45 -17
  57. package/lib/module/InterstitialAd.js.map +1 -1
  58. package/lib/module/LightPopupAd.js +63 -43
  59. package/lib/module/LightPopupAd.js.map +1 -1
  60. package/lib/module/RewardedAd.js +44 -18
  61. package/lib/module/RewardedAd.js.map +1 -1
  62. package/lib/module/index.js +1 -1
  63. package/lib/module/index.js.map +1 -1
  64. package/lib/module/nativeAd/NativeAdView.js +5 -1
  65. package/lib/module/nativeAd/NativeAdView.js.map +1 -1
  66. package/lib/module/nativeAd/NativeAdViewComponents.js.map +1 -1
  67. package/lib/module/nativeAd/NativeAdViewProvider.js.map +1 -1
  68. package/lib/module/package.json +1 -0
  69. package/lib/typescript/commonjs/plugin/src/index.d.ts +19 -0
  70. package/lib/typescript/commonjs/plugin/src/index.d.ts.map +1 -0
  71. package/lib/typescript/commonjs/plugin/src/skAdNetworkIds.d.ts +6 -0
  72. package/lib/typescript/commonjs/plugin/src/skAdNetworkIds.d.ts.map +1 -0
  73. package/lib/typescript/commonjs/plugin/src/withAndroid.d.ts +8 -0
  74. package/lib/typescript/commonjs/plugin/src/withAndroid.d.ts.map +1 -0
  75. package/lib/typescript/commonjs/plugin/src/withIos.d.ts +8 -0
  76. package/lib/typescript/commonjs/plugin/src/withIos.d.ts.map +1 -0
  77. package/lib/typescript/commonjs/src/AdBannerView.d.ts +124 -2
  78. package/lib/typescript/commonjs/src/AdBannerView.d.ts.map +1 -1
  79. package/lib/typescript/commonjs/src/AppOpenAd.d.ts +6 -0
  80. package/lib/typescript/commonjs/src/AppOpenAd.d.ts.map +1 -1
  81. package/lib/typescript/commonjs/src/ErrorCode.d.ts.map +1 -1
  82. package/lib/typescript/commonjs/src/EventEmitter.d.ts.map +1 -1
  83. package/lib/typescript/commonjs/src/InterstitialAd.d.ts +6 -0
  84. package/lib/typescript/commonjs/src/InterstitialAd.d.ts.map +1 -1
  85. package/lib/typescript/commonjs/src/LightPopupAd.d.ts +6 -0
  86. package/lib/typescript/commonjs/src/LightPopupAd.d.ts.map +1 -1
  87. package/lib/typescript/commonjs/src/RewardedAd.d.ts +6 -0
  88. package/lib/typescript/commonjs/src/RewardedAd.d.ts.map +1 -1
  89. package/lib/typescript/commonjs/src/nativeAd/NativeAdView.d.ts +124 -2
  90. package/lib/typescript/commonjs/src/nativeAd/NativeAdView.d.ts.map +1 -1
  91. package/lib/typescript/commonjs/src/nativeAd/NativeAdViewComponents.d.ts.map +1 -1
  92. package/lib/typescript/commonjs/src/nativeAd/NativeAdViewProvider.d.ts.map +1 -1
  93. package/lib/typescript/commonjs/src/types/AdBannerViewProps.d.ts +2 -2
  94. package/lib/typescript/commonjs/src/types/AdBannerViewProps.d.ts.map +1 -1
  95. package/lib/typescript/commonjs/src/types/AdInfo.d.ts.map +1 -1
  96. package/lib/typescript/commonjs/src/types/AdProps.d.ts +2 -2
  97. package/lib/typescript/commonjs/src/types/AdProps.d.ts.map +1 -1
  98. package/lib/typescript/commonjs/src/types/DaroMMobileAds.d.ts.map +1 -1
  99. package/lib/typescript/commonjs/src/types/NativeAdViewProps.d.ts.map +1 -1
  100. package/lib/typescript/module/plugin/src/index.d.ts +19 -0
  101. package/lib/typescript/module/plugin/src/index.d.ts.map +1 -0
  102. package/lib/typescript/module/plugin/src/skAdNetworkIds.d.ts +6 -0
  103. package/lib/typescript/module/plugin/src/skAdNetworkIds.d.ts.map +1 -0
  104. package/lib/typescript/module/plugin/src/withAndroid.d.ts +8 -0
  105. package/lib/typescript/module/plugin/src/withAndroid.d.ts.map +1 -0
  106. package/lib/typescript/module/plugin/src/withIos.d.ts +8 -0
  107. package/lib/typescript/module/plugin/src/withIos.d.ts.map +1 -0
  108. package/lib/typescript/module/src/AdBannerView.d.ts +124 -2
  109. package/lib/typescript/module/src/AdBannerView.d.ts.map +1 -1
  110. package/lib/typescript/module/src/AppOpenAd.d.ts +6 -0
  111. package/lib/typescript/module/src/AppOpenAd.d.ts.map +1 -1
  112. package/lib/typescript/module/src/ErrorCode.d.ts.map +1 -1
  113. package/lib/typescript/module/src/EventEmitter.d.ts.map +1 -1
  114. package/lib/typescript/module/src/InterstitialAd.d.ts +6 -0
  115. package/lib/typescript/module/src/InterstitialAd.d.ts.map +1 -1
  116. package/lib/typescript/module/src/LightPopupAd.d.ts +6 -0
  117. package/lib/typescript/module/src/LightPopupAd.d.ts.map +1 -1
  118. package/lib/typescript/module/src/RewardedAd.d.ts +6 -0
  119. package/lib/typescript/module/src/RewardedAd.d.ts.map +1 -1
  120. package/lib/typescript/module/src/nativeAd/NativeAdView.d.ts +124 -2
  121. package/lib/typescript/module/src/nativeAd/NativeAdView.d.ts.map +1 -1
  122. package/lib/typescript/module/src/nativeAd/NativeAdViewComponents.d.ts.map +1 -1
  123. package/lib/typescript/module/src/nativeAd/NativeAdViewProvider.d.ts.map +1 -1
  124. package/lib/typescript/module/src/types/AdBannerViewProps.d.ts +2 -2
  125. package/lib/typescript/module/src/types/AdBannerViewProps.d.ts.map +1 -1
  126. package/lib/typescript/module/src/types/AdInfo.d.ts.map +1 -1
  127. package/lib/typescript/module/src/types/AdProps.d.ts +2 -2
  128. package/lib/typescript/module/src/types/AdProps.d.ts.map +1 -1
  129. package/lib/typescript/module/src/types/DaroMMobileAds.d.ts.map +1 -1
  130. package/lib/typescript/module/src/types/NativeAdViewProps.d.ts.map +1 -1
  131. package/package.json +88 -105
  132. package/plugin/build/index.d.ts +18 -0
  133. package/plugin/build/index.js +71 -0
  134. package/plugin/build/skAdNetworkIds.d.ts +5 -0
  135. package/plugin/build/skAdNetworkIds.js +205 -0
  136. package/plugin/build/withAndroid.d.ts +7 -0
  137. package/plugin/build/withAndroid.js +140 -0
  138. package/plugin/build/withIos.d.ts +7 -0
  139. package/plugin/build/withIos.js +83 -0
  140. package/react-native-daro.podspec +25 -0
  141. package/src/AdBannerView.tsx +54 -17
  142. package/src/AppOpenAd.ts +59 -15
  143. package/src/ErrorCode.ts +1 -2
  144. package/src/EventEmitter.ts +5 -2
  145. package/src/InterstitialAd.ts +73 -17
  146. package/src/LightPopupAd.ts +86 -46
  147. package/src/RewardedAd.ts +70 -18
  148. package/src/index.tsx +1 -1
  149. package/src/nativeAd/NativeAdView.tsx +65 -14
  150. package/src/nativeAd/NativeAdViewComponents.tsx +54 -27
  151. package/src/nativeAd/NativeAdViewProvider.tsx +17 -7
  152. package/src/types/AdBannerViewProps.ts +11 -11
  153. package/src/types/AdInfo.ts +17 -17
  154. package/src/types/AdProps.ts +8 -9
  155. package/src/types/DaroMMobileAds.ts +3 -6
  156. package/src/types/NativeAdViewProps.ts +5 -5
  157. package/src/types/index.ts +1 -1
  158. package/android/gradle.properties +0 -5
  159. package/android/src/main/AndroidManifestNew.xml +0 -7
  160. package/android/src/main/java/com/darom/view/DaroMAdBannerViewContainer.kt +0 -163
  161. package/android/src/main/res/layout/layout_activity_transparent.xml +0 -7
  162. package/android/src/main/res/values/styles.xml +0 -11
  163. package/ios/DaroM-Bridging-Header.h +0 -6
  164. package/react-native-daro-m.podspec +0 -44
@@ -0,0 +1,417 @@
1
+ package com.daro.reactnative.view
2
+
3
+ import android.annotation.SuppressLint
4
+ import android.graphics.Rect
5
+ import android.view.View
6
+ import android.view.ViewTreeObserver
7
+ import android.view.ViewGroup
8
+ import android.widget.FrameLayout
9
+ import androidx.core.view.children
10
+ import androidx.core.view.isVisible
11
+ import com.daro.reactnative.event.AdViewEvent
12
+ import com.daro.reactnative.util.AdInfoUtil
13
+ import com.daro.reactnative.util.EventEmitterUtil.sendNativeViewEvent
14
+ import com.facebook.react.bridge.ReactContext
15
+ import com.facebook.react.views.view.ReactViewGroup
16
+ import droom.daro.core.adunit.DaroBannerAdUnit
17
+ import droom.daro.core.model.DaroAdInfo
18
+ import droom.daro.core.model.DaroAdLoadError
19
+ import droom.daro.core.model.DaroBannerSize
20
+ import droom.daro.core.model.DaroViewAd
21
+ import droom.daro.view.DaroAdViewListener
22
+ import droom.daro.view.DaroBannerAdView
23
+
24
+ @SuppressLint("ViewConstructor")
25
+ class DaroMAdBannerViewContainer(val context: ReactContext) : ReactViewGroup(context),
26
+ DaroAdViewListener {
27
+ private companion object {
28
+ private const val MAX_PENDING_LOAD_RETRIES = 10
29
+ private const val PENDING_LOAD_RETRY_DELAY_MS = 100L
30
+ }
31
+
32
+ private var adView: DaroBannerAdView? = null
33
+
34
+ internal var adUnitId: String = ""
35
+
36
+ internal var adSize: DaroBannerSize? = null
37
+
38
+ internal var loadOnMount: Boolean = true
39
+
40
+ private var isAdVisible: Boolean = true
41
+ private var isAdPaused: Boolean = false
42
+ private var hasRequestedInitialLoad: Boolean = false
43
+ private var hasPendingLoad: Boolean = false
44
+ private var isPendingLoadRetryScheduled: Boolean = false
45
+ private var pendingLoadRetryCount: Int = 0
46
+ private var pendingLoadRetryRunnable: Runnable? = null
47
+ private var hasScheduledLoadedAdDrawActivation: Boolean = false
48
+ private var hasPulsedLoadedAdAttach: Boolean = false
49
+ private var activatedAdChild: View? = null
50
+ private var pulsedAdChild: View? = null
51
+ private val visibleRect = Rect()
52
+
53
+ fun loadAd() {
54
+ (adView ?: buildAdView())?.apply {
55
+ adView = this
56
+
57
+ if (this.parent == null) {
58
+ this.layoutParams = ViewGroup.LayoutParams(
59
+ ViewGroup.LayoutParams.MATCH_PARENT,
60
+ ViewGroup.LayoutParams.MATCH_PARENT,
61
+ )
62
+ this@DaroMAdBannerViewContainer.addView(this)
63
+ }
64
+
65
+ layoutAdView()
66
+ if (!canLoadAd()) {
67
+ if (!hasPendingLoad) {
68
+ pendingLoadRetryCount = 0
69
+ }
70
+ hasPendingLoad = true
71
+ schedulePendingLoadRetry()
72
+ return
73
+ }
74
+
75
+ hasPendingLoad = false
76
+ pendingLoadRetryCount = 0
77
+ cancelPendingLoadRetry()
78
+ hasScheduledLoadedAdDrawActivation = false
79
+ hasPulsedLoadedAdAttach = false
80
+ activatedAdChild = null
81
+ pulsedAdChild = null
82
+ loadAd()
83
+ }
84
+ }
85
+
86
+ private fun buildAdView(): DaroBannerAdView? {
87
+ if (adUnitId.isEmpty() || adSize == null) {
88
+ return null
89
+ }
90
+
91
+ return DaroBannerAdView(
92
+ context,
93
+ DaroBannerAdUnit(
94
+ key = adUnitId,
95
+ placement = adUnitId,
96
+ bannerSize = adSize!!,
97
+ )
98
+ ).also { view ->
99
+ view.setListener(this)
100
+ view.setOnHierarchyChangeListener(object : ViewGroup.OnHierarchyChangeListener {
101
+ override fun onChildViewAdded(parent: View, child: View) {
102
+ if (activatedAdChild !== child) {
103
+ hasScheduledLoadedAdDrawActivation = false
104
+ hasPulsedLoadedAdAttach = false
105
+ activatedAdChild = null
106
+ pulsedAdChild = null
107
+ }
108
+
109
+ layoutAdView()
110
+ layoutLoadedAdChild(child)
111
+ }
112
+
113
+ override fun onChildViewRemoved(parent: View, child: View) = Unit
114
+ })
115
+ }
116
+ }
117
+
118
+ fun destroy() {
119
+ cancelPendingLoadRetry()
120
+ hasPendingLoad = false
121
+ pendingLoadRetryCount = 0
122
+ hasScheduledLoadedAdDrawActivation = false
123
+ hasPulsedLoadedAdAttach = false
124
+ activatedAdChild = null
125
+ pulsedAdChild = null
126
+ adView?.setOnHierarchyChangeListener(null)
127
+ adView?.destroy()
128
+ adView = null
129
+ }
130
+
131
+ fun setAdVisibility(visible: Boolean) {
132
+ isAdVisible = visible
133
+ this.isVisible = visible
134
+ adView?.isVisible = visible
135
+
136
+ if (visible) {
137
+ resumeAd()
138
+ loadPendingAdIfReady()
139
+ } else {
140
+ cancelPendingLoadRetry()
141
+ pauseAd()
142
+ }
143
+ }
144
+
145
+ fun pauseAd() {
146
+ cancelPendingLoadRetry()
147
+ if (!isAdPaused) {
148
+ isAdPaused = true
149
+ adView?.pause()
150
+ }
151
+ }
152
+
153
+ fun resumeAd() {
154
+ if (isAdPaused) {
155
+ isAdPaused = false
156
+ adView?.resume()
157
+ }
158
+ loadPendingAdIfReady()
159
+ }
160
+
161
+ override fun onAdClicked(adInfo: DaroAdInfo) {
162
+ sendNativeViewEvent(
163
+ reactContext = context,
164
+ event = AdViewEvent.ON_AD_CLICKED,
165
+ params = AdInfoUtil.getAdInfo(adUnitId, adInfo)
166
+ )
167
+ }
168
+
169
+ override fun onAdImpression(adInfo: DaroAdInfo) {
170
+ sendNativeViewEvent(
171
+ reactContext = context,
172
+ event = AdViewEvent.ON_AD_IMPRESSION,
173
+ params = AdInfoUtil.getAdInfo(adUnitId, adInfo),
174
+ )
175
+ }
176
+
177
+ override fun onAdLoadFail(err: DaroAdLoadError) {
178
+ sendNativeViewEvent(
179
+ reactContext = context,
180
+ event = AdViewEvent.ON_AD_FAILED_TO_LOAD,
181
+ params = AdInfoUtil.getAdLoadFailedInfo(adUnitId, err),
182
+ )
183
+ }
184
+
185
+ override fun onAdLoadSuccess(
186
+ ad: DaroViewAd,
187
+ adInfo: DaroAdInfo,
188
+ ) {
189
+ layoutLoadedAdView()
190
+
191
+ sendNativeViewEvent(
192
+ reactContext = context,
193
+ event = AdViewEvent.ON_AD_LOADED,
194
+ params = AdInfoUtil.getAdInfo(adUnitId, adInfo),
195
+ )
196
+
197
+ post {
198
+ layoutLoadedAdView()
199
+ }
200
+ }
201
+
202
+ override fun requestLayout() {
203
+ super.requestLayout()
204
+
205
+ // https://stackoverflow.com/a/39838774/5477988
206
+ // This is required to ensure ad refreshes render correctly in RN Android due to known issue
207
+ // where `getWidth()` and `getHeight()` return 0 on attach
208
+ post {
209
+ layoutAdView()
210
+ loadPendingAdIfReady()
211
+ }
212
+ }
213
+
214
+ override fun onAttachedToWindow() {
215
+ super.onAttachedToWindow()
216
+ loadPendingAdIfReady()
217
+ }
218
+
219
+ override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
220
+ super.onSizeChanged(w, h, oldw, oldh)
221
+ layoutAdView()
222
+ loadPendingAdIfReady()
223
+ }
224
+
225
+ override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
226
+ super.onLayout(changed, left, top, right, bottom)
227
+ layoutAdView()
228
+ loadPendingAdIfReady()
229
+ }
230
+
231
+ override fun onWindowVisibilityChanged(visibility: Int) {
232
+ super.onWindowVisibilityChanged(visibility)
233
+
234
+ if (visibility == View.VISIBLE) {
235
+ loadPendingAdIfReady()
236
+ }
237
+ }
238
+
239
+ private fun layoutAdView() {
240
+ if (width <= 0 || height <= 0) {
241
+ return
242
+ }
243
+
244
+ try {
245
+ adView?.measure(
246
+ MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
247
+ MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)
248
+ )
249
+
250
+ adView?.layout(0, 0, width, height)
251
+ } catch (_: Exception) {
252
+ // Ignore
253
+ }
254
+ }
255
+
256
+ private fun layoutLoadedAdView() {
257
+ layoutAdView()
258
+ adView?.children?.firstOrNull()?.let { layoutLoadedAdChild(it) }
259
+ }
260
+
261
+ private fun layoutLoadedAdChild(child: View) {
262
+ layoutLoadedAdChild(child, scheduleDrawActivation = true)
263
+ }
264
+
265
+ private fun layoutLoadedAdChild(child: View, scheduleDrawActivation: Boolean) {
266
+ if (width <= 0 || height <= 0) {
267
+ return
268
+ }
269
+
270
+ ensureMatchParentLayoutParams(child)
271
+
272
+ child.measure(
273
+ MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
274
+ MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)
275
+ )
276
+
277
+ child.layout(0, 0, width, height)
278
+ child.requestLayout()
279
+ adView?.requestLayout()
280
+
281
+ if (scheduleDrawActivation) {
282
+ scheduleLoadedAdDrawActivation(child)
283
+ }
284
+ }
285
+
286
+ private fun scheduleLoadedAdDrawActivation(child: View) {
287
+ if (hasScheduledLoadedAdDrawActivation && activatedAdChild === child) {
288
+ return
289
+ }
290
+
291
+ hasScheduledLoadedAdDrawActivation = true
292
+ activatedAdChild = child
293
+ child.viewTreeObserver.addOnPreDrawListener(object : ViewTreeObserver.OnPreDrawListener {
294
+ override fun onPreDraw(): Boolean {
295
+ if (child.viewTreeObserver.isAlive) {
296
+ child.viewTreeObserver.removeOnPreDrawListener(this)
297
+ }
298
+
299
+ layoutLoadedAdChild(child)
300
+ pulseLoadedAdAttachIfNeeded(child)
301
+ adView?.requestLayout()
302
+ adView?.invalidate()
303
+ child.requestLayout()
304
+ child.invalidate()
305
+ return true
306
+ }
307
+ })
308
+ }
309
+
310
+ private fun pulseLoadedAdAttachIfNeeded(child: View) {
311
+ if ((hasPulsedLoadedAdAttach && pulsedAdChild === child) || !isStableVisibleAdChild(child)) {
312
+ return
313
+ }
314
+
315
+ hasPulsedLoadedAdAttach = true
316
+ pulsedAdChild = child
317
+ post {
318
+ val parent = child.parent as? ViewGroup
319
+ val currentAdView = adView
320
+ if (parent == null || currentAdView == null || parent !== currentAdView) {
321
+ return@post
322
+ }
323
+
324
+ parent.removeView(child)
325
+ ensureMatchParentLayoutParams(child)
326
+ currentAdView.addView(child)
327
+ layoutAdView()
328
+ layoutLoadedAdChild(child, scheduleDrawActivation = false)
329
+ child.requestLayout()
330
+ child.invalidate()
331
+ currentAdView.requestLayout()
332
+ currentAdView.invalidate()
333
+ }
334
+ }
335
+
336
+ private fun isStableVisibleAdChild(child: View): Boolean {
337
+ val hasGlobalVisibleRect = child.getGlobalVisibleRect(visibleRect)
338
+ return width > 0 &&
339
+ height > 0 &&
340
+ child.width > 0 &&
341
+ child.height > 0 &&
342
+ child.isAttachedToWindow &&
343
+ child.isShown &&
344
+ child.windowVisibility == View.VISIBLE &&
345
+ hasGlobalVisibleRect &&
346
+ visibleRect.width() > 0 &&
347
+ visibleRect.height() > 0
348
+ }
349
+
350
+ private fun ensureMatchParentLayoutParams(child: View) {
351
+ val layoutParams = child.layoutParams
352
+ if (layoutParams == null) {
353
+ child.layoutParams = FrameLayout.LayoutParams(
354
+ ViewGroup.LayoutParams.MATCH_PARENT,
355
+ ViewGroup.LayoutParams.MATCH_PARENT,
356
+ )
357
+ return
358
+ }
359
+
360
+ layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT
361
+ layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT
362
+ child.layoutParams = layoutParams
363
+ }
364
+
365
+ private fun loadPendingAdIfReady() {
366
+ if (!hasPendingLoad) {
367
+ return
368
+ }
369
+
370
+ if (canLoadAd()) {
371
+ loadAd()
372
+ } else {
373
+ schedulePendingLoadRetry()
374
+ }
375
+ }
376
+
377
+ private fun schedulePendingLoadRetry() {
378
+ if (isPendingLoadRetryScheduled || pendingLoadRetryCount >= MAX_PENDING_LOAD_RETRIES) {
379
+ return
380
+ }
381
+
382
+ isPendingLoadRetryScheduled = true
383
+ pendingLoadRetryCount += 1
384
+ val retryRunnable = Runnable {
385
+ pendingLoadRetryRunnable = null
386
+ isPendingLoadRetryScheduled = false
387
+ loadPendingAdIfReady()
388
+ }
389
+ pendingLoadRetryRunnable = retryRunnable
390
+ postDelayed(retryRunnable, PENDING_LOAD_RETRY_DELAY_MS)
391
+ }
392
+
393
+ private fun cancelPendingLoadRetry() {
394
+ pendingLoadRetryRunnable?.let { removeCallbacks(it) }
395
+ pendingLoadRetryRunnable = null
396
+ isPendingLoadRetryScheduled = false
397
+ }
398
+
399
+ private fun canLoadAd(): Boolean {
400
+ return isAdVisible &&
401
+ isAttachedToWindow &&
402
+ width > 0 &&
403
+ height > 0 &&
404
+ windowVisibility == View.VISIBLE
405
+ }
406
+
407
+ fun onSetProps() {
408
+ if (loadOnMount && !hasRequestedInitialLoad && canBuildAdView()) {
409
+ hasRequestedInitialLoad = true
410
+ loadAd()
411
+ }
412
+ }
413
+
414
+ private fun canBuildAdView(): Boolean {
415
+ return adUnitId.isNotEmpty() && adSize != null
416
+ }
417
+ }
@@ -1,4 +1,4 @@
1
- package com.darom.view
1
+ package com.daro.reactnative.view
2
2
 
3
3
  import android.annotation.SuppressLint
4
4
  import android.os.Handler
@@ -10,9 +10,9 @@ import android.view.ViewGroup
10
10
  import android.widget.ImageView
11
11
  import androidx.annotation.IdRes
12
12
  import androidx.core.view.children
13
- import com.darom.event.AdViewEvent
14
- import com.darom.util.AdInfoUtil
15
- import com.darom.util.EventEmitterUtil.sendNativeViewEvent
13
+ import com.daro.reactnative.event.AdViewEvent
14
+ import com.daro.reactnative.util.AdInfoUtil
15
+ import com.daro.reactnative.util.EventEmitterUtil.sendNativeViewEvent
16
16
  import com.facebook.react.bridge.ReactContext
17
17
  import com.facebook.react.views.text.ReactTextView
18
18
  import com.facebook.react.views.view.ReactViewGroup
package/app.plugin.js ADDED
@@ -0,0 +1 @@
1
+ module.exports = require('./plugin/build').default;
@@ -1,4 +1,4 @@
1
- import Daro
1
+ import React
2
2
 
3
3
  @objc(DaroMAdBannerViewManager)
4
4
  class DaroMAdBannerViewManager: RCTViewManager {
@@ -1,12 +1,13 @@
1
- import Daro
1
+ import React
2
2
 
3
3
  // MARK: - AppOpen Ad Methods
4
4
 
5
5
  extension DaroMModule {
6
-
7
- @objc(isAppOpenAdReady:::)
6
+
7
+ @objc(isAppOpenAdReady::::)
8
8
  func isAppOpenAdReady(
9
- _ adUnitId: String,
9
+ _ requestId: NSNumber,
10
+ adUnitId: String,
10
11
  resolve: RCTPromiseResolveBlock,
11
12
  reject: RCTPromiseRejectBlock
12
13
  ) {
@@ -15,28 +16,31 @@ extension DaroMModule {
15
16
  resolve(false)
16
17
  return
17
18
  }
18
- resolve(appOpenAds[adUnitId]?.loadedAd != nil)
19
+ resolve(appOpenAds[requestId.intValue]?.loadedAd != nil)
19
20
  }
20
21
 
21
- @objc(loadAppOpenAd:::)
22
+ @objc(loadAppOpenAd::::)
22
23
  func loadAppOpenAd(
23
- _ adUnitId: String,
24
+ _ requestId: NSNumber,
25
+ adUnitId: String,
24
26
  resolve: RCTPromiseResolveBlock,
25
27
  reject: RCTPromiseRejectBlock
26
28
  ) {
27
- let appOpenAdLoader = retrieveAppOpenLoader(for: adUnitId)
29
+ let appOpenAdLoader = retrieveAppOpenLoader(requestId: requestId.intValue, adUnitId: adUnitId)
28
30
  appOpenAdLoader.loadAd()
29
31
  resolve(Void())
30
32
  }
31
33
 
32
- @objc(showAppOpenAd::::)
34
+ @objc(showAppOpenAd::::::)
33
35
  func showAppOpenAd(
34
- _ adUnitId: String,
36
+ _ requestId: NSNumber,
37
+ adUnitId: String,
38
+ placement: String?,
35
39
  customData: String?,
36
40
  resolve: @escaping RCTPromiseResolveBlock,
37
41
  reject: RCTPromiseRejectBlock
38
42
  ) {
39
- guard let loadedAd = appOpenAds[adUnitId]?.loadedAd else {
43
+ guard let loadedAd = appOpenAds[requestId.intValue]?.loadedAd else {
40
44
  reject("APPOPEN_NOT_LOADED", "AppOpen ad not loaded", nil)
41
45
  return
42
46
  }
@@ -46,53 +50,52 @@ extension DaroMModule {
46
50
  }
47
51
  }
48
52
 
49
- func retrieveAppOpenLoader(for unitId: String) -> DaroAppOpenAdLoader {
50
- if let appOpenLoader = appOpenAds[unitId] {
53
+ func retrieveAppOpenLoader(requestId: Int, adUnitId: String) -> DaroAppOpenAdLoader {
54
+ if let appOpenLoader = appOpenAds[requestId] {
51
55
  return appOpenLoader.loader
52
56
  } else {
53
- let appOpenLoader = DaroAppOpenAdLoader(unit: DaroAdUnit(unitId: unitId))
57
+ let appOpenLoader = DaroAppOpenAdLoader(unit: DaroAdUnit(unitId: adUnitId))
54
58
  appOpenLoader.listener.onAdClicked = { [weak self] adInfo in
55
- DaroMModule.logger.debug("[DARO] Sample Interstitial Ad clicked")
56
- self?.sendEvent(with: .onAppOpenAdClickedEvent, body: adInfo?.toBody)
59
+ DaroMModule.logger.debug("[DARO] Sample AppOpen Ad clicked")
60
+ self?.sendEvent(with: .onAppOpenAdClickedEvent, body: adInfo?.toBody(requestId: requestId))
57
61
  }
58
62
 
59
63
  appOpenLoader.listener.onAdImpression = { [weak self] adInfo in
60
- DaroMModule.logger.debug("[DARO] Sample Interstitial Ad impression")
61
- self?.interstitials[unitId]?.loadedAd = nil
62
- self?.sendEvent(with: .onAppOpenAdImpressionRecordedEvent, body: adInfo?.toBody)
64
+ DaroMModule.logger.debug("[DARO] Sample AppOpen Ad impression")
65
+ self?.appOpenAds[requestId]?.loadedAd = nil
66
+ self?.sendEvent(with: .onAppOpenAdImpressionRecordedEvent, body: adInfo?.toBody(requestId: requestId))
63
67
  }
64
68
 
65
69
  appOpenLoader.listener.onAdLoadSuccess = { [weak self] ad, adInfo in
66
- DaroMModule.logger.debug("[DARO] Sample Interstitial Ad loaded")
67
- self?.appOpenAds[unitId]?.loadedAd = ad
68
- self?.sendEvent(with: .onAppOpenAdLoadedEvent, body: adInfo?.toBody)
69
- self?.setupAppOpenListener(for: ad)
70
+ DaroMModule.logger.debug("[DARO] Sample AppOpen Ad loaded")
71
+ self?.appOpenAds[requestId]?.loadedAd = ad
72
+ self?.sendEvent(with: .onAppOpenAdLoadedEvent, body: adInfo?.toBody(requestId: requestId))
73
+ self?.setupAppOpenListener(for: ad, requestId: requestId)
70
74
  }
71
75
 
72
76
  appOpenLoader.listener.onAdLoadFail = { [weak self] error in
73
- DaroMModule.logger.debug("[DARO] Sample Interstitial Ad failed: \(error)")
74
- self?.sendEvent(with: .onAppOpenAdLoadFailedEvent, body: error.toBody)
77
+ DaroMModule.logger.debug("[DARO] Sample AppOpen Ad failed: \(error)")
78
+ self?.sendEvent(with: .onAppOpenAdLoadFailedEvent, body: error.toBody(requestId: requestId))
75
79
  }
76
- self.appOpenAds[unitId] = AppOpenAd(loader: appOpenLoader)
80
+ self.appOpenAds[requestId] = AppOpenAd(loader: appOpenLoader)
77
81
  return appOpenLoader
78
82
  }
79
83
  }
80
84
 
81
- private func setupAppOpenListener(for ad: DaroAppOpenAd) {
85
+ private func setupAppOpenListener(for ad: DaroAppOpenAd, requestId: Int) {
82
86
  ad.appOpenAdListener.onShown = { [weak self] adInfo in
83
87
  DaroMModule.logger.debug("[DARO] Sample AppOpen Ad displayed")
84
- self?.sendEvent(with: .onAppOpenAdDisplayedEvent, body: adInfo?.toBody)
88
+ self?.sendEvent(with: .onAppOpenAdDisplayedEvent, body: adInfo?.toBody(requestId: requestId))
85
89
  }
86
90
 
87
91
  ad.appOpenAdListener.onDismiss = { [weak self] adInfo in
88
92
  DaroMModule.logger.debug("[DARO] Sample AppOpen Ad hidden")
89
- self?.sendEvent(with: .onAppOpenAdHiddenEvent, body: adInfo?.toBody)
93
+ self?.sendEvent(with: .onAppOpenAdHiddenEvent, body: adInfo?.toBody(requestId: requestId))
90
94
  }
91
95
 
92
96
  ad.appOpenAdListener.onFailedToShow = { [weak self] adInfo, error in
93
97
  DaroMModule.logger.debug("[DARO] Sample AppOpen Ad failed to display")
94
- self?.sendEvent(with: .onAppOpenAdFailedToDisplayEvent, body: adInfo?.toBody)
98
+ self?.sendEvent(with: .onAppOpenAdFailedToDisplayEvent, body: adInfo?.toBody(requestId: requestId))
95
99
  }
96
100
  }
97
101
  }
98
-
@@ -1,12 +1,13 @@
1
- import Daro
1
+ import React
2
2
 
3
3
  // MARK: - Interstitial Ad Methods
4
4
 
5
5
  extension DaroMModule {
6
-
7
- @objc(isInterstitialReady:::)
6
+
7
+ @objc(isInterstitialReady::::)
8
8
  func isInterstitialReady(
9
- _ adUnitId: String,
9
+ _ requestId: NSNumber,
10
+ adUnitId: String,
10
11
  resolve: RCTPromiseResolveBlock,
11
12
  reject: RCTPromiseRejectBlock
12
13
  ) {
@@ -15,27 +16,29 @@ extension DaroMModule {
15
16
  resolve(false)
16
17
  return
17
18
  }
18
- resolve(interstitials[adUnitId]?.loadedAd != nil)
19
+ resolve(interstitials[requestId.intValue]?.loadedAd != nil)
19
20
  }
20
21
 
21
- @objc(loadInterstitial:::)
22
+ @objc(loadInterstitial::::)
22
23
  func loadInterstitial(
23
- _ adUnitId: String,
24
+ _ requestId: NSNumber,
25
+ adUnitId: String,
24
26
  resolve: RCTPromiseResolveBlock,
25
27
  reject: RCTPromiseRejectBlock
26
28
  ) {
27
- let interstitialLoader = retrieveInterstitialLoader(for: adUnitId)
29
+ let interstitialLoader = retrieveInterstitialLoader(requestId: requestId.intValue, adUnitId: adUnitId)
28
30
  interstitialLoader.loadAd()
29
31
  resolve(Void())
30
32
  }
31
33
 
32
- @objc(showInterstitial:::)
34
+ @objc(showInterstitial::::)
33
35
  func showInterstitial(
34
- _ adUnitId: String,
36
+ _ requestId: NSNumber,
37
+ adUnitId: String,
35
38
  resolve: @escaping RCTPromiseResolveBlock,
36
39
  reject: @escaping RCTPromiseRejectBlock
37
40
  ) {
38
- guard let loadedAd = interstitials[adUnitId]?.loadedAd else {
41
+ guard let loadedAd = interstitials[requestId.intValue]?.loadedAd else {
39
42
  reject("INTERSTITIAL_NOT_LOADED", "Interstitial ad not loaded", nil)
40
43
  return
41
44
  }
@@ -49,52 +52,52 @@ extension DaroMModule {
49
52
  }
50
53
  }
51
54
 
52
- func retrieveInterstitialLoader(for unitId: String) -> DaroInterstitialAdLoader {
53
- if let interstitialAd = interstitials[unitId] {
55
+ func retrieveInterstitialLoader(requestId: Int, adUnitId: String) -> DaroInterstitialAdLoader {
56
+ if let interstitialAd = interstitials[requestId] {
54
57
  return interstitialAd.loader
55
58
  } else {
56
- let interstitialLoader = DaroInterstitialAdLoader(unit: DaroAdUnit(unitId: unitId))
59
+ let interstitialLoader = DaroInterstitialAdLoader(unit: DaroAdUnit(unitId: adUnitId))
57
60
  interstitialLoader.listener.onAdClicked = { [weak self] adInfo in
58
61
  DaroMModule.logger.debug("[DARO] Sample Interstitial Ad clicked")
59
- self?.sendEvent(with: .onInterstitialClickedEvent, body: adInfo?.toBody)
62
+ self?.sendEvent(with: .onInterstitialClickedEvent, body: adInfo?.toBody(requestId: requestId))
60
63
  }
61
64
 
62
65
  interstitialLoader.listener.onAdImpression = { [weak self] adInfo in
63
66
  DaroMModule.logger.debug("[DARO] Sample Interstitial Ad impression")
64
- self?.interstitials[unitId]?.loadedAd = nil
65
- self?.sendEvent(with: .onInterstitialAdImpressionRecordedEvent, body: adInfo?.toBody)
67
+ self?.interstitials[requestId]?.loadedAd = nil
68
+ self?.sendEvent(with: .onInterstitialAdImpressionRecordedEvent, body: adInfo?.toBody(requestId: requestId))
66
69
  }
67
70
 
68
71
  interstitialLoader.listener.onAdLoadSuccess = { [weak self] ad, adInfo in
69
72
  DaroMModule.logger.debug("[DARO] Sample Interstitial Ad loaded")
70
- self?.interstitials[unitId]?.loadedAd = ad
71
- self?.sendEvent(with: .onInterstitialLoadedEvent, body: adInfo?.toBody)
72
- self?.setupInterstitialListener(for: ad)
73
+ self?.interstitials[requestId]?.loadedAd = ad
74
+ self?.sendEvent(with: .onInterstitialLoadedEvent, body: adInfo?.toBody(requestId: requestId))
75
+ self?.setupInterstitialListener(for: ad, requestId: requestId)
73
76
  }
74
77
 
75
78
  interstitialLoader.listener.onAdLoadFail = { [weak self] error in
76
79
  DaroMModule.logger.debug("[DARO] Sample Interstitial Ad failed: \(error)")
77
- self?.sendEvent(with: .onInterstitialLoadFailedEvent, body: error.toBody)
80
+ self?.sendEvent(with: .onInterstitialLoadFailedEvent, body: error.toBody(requestId: requestId))
78
81
  }
79
- self.interstitials[unitId] = InterstitialAd(loader: interstitialLoader)
82
+ self.interstitials[requestId] = InterstitialAd(loader: interstitialLoader)
80
83
  return interstitialLoader
81
84
  }
82
85
  }
83
86
 
84
- private func setupInterstitialListener(for ad: DaroInterstitialAd) {
87
+ private func setupInterstitialListener(for ad: DaroInterstitialAd, requestId: Int) {
85
88
  ad.interstitialListener.onShown = { [weak self] adInfo in
86
89
  DaroMModule.logger.debug("[DARO] Sample Interstitial Ad displayed")
87
- self?.sendEvent(with: .onInterstitialDisplayedEvent, body: adInfo?.toBody)
90
+ self?.sendEvent(with: .onInterstitialDisplayedEvent, body: adInfo?.toBody(requestId: requestId))
88
91
  }
89
92
 
90
93
  ad.interstitialListener.onDismiss = { [weak self] adInfo in
91
94
  DaroMModule.logger.debug("[DARO] Sample Interstitial Ad hidden")
92
- self?.sendEvent(with: .onInterstitialHiddenEvent, body: adInfo?.toBody)
95
+ self?.sendEvent(with: .onInterstitialHiddenEvent, body: adInfo?.toBody(requestId: requestId))
93
96
  }
94
97
 
95
98
  ad.interstitialListener.onFailedToShow = { [weak self] adInfo, error in
96
99
  DaroMModule.logger.debug("[DARO] Sample Interstitial Ad failed to display")
97
- self?.sendEvent(with: .onInterstitialAdFailedToDisplayEvent, body: adInfo?.toBody)
100
+ self?.sendEvent(with: .onInterstitialAdFailedToDisplayEvent, body: adInfo?.toBody(requestId: requestId))
98
101
  }
99
102
  }
100
103
  }