@thealteroffice/react-native-adgeist 0.0.34 → 0.0.35-beta
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 +122 -12
- package/android/build.gradle +1 -22
- package/android/src/main/java/com/adgeist/components/HTML5AdViewManagerImpl.kt +42 -30
- package/android/src/main/java/com/adgeist/components/ReactAdView.kt +21 -0
- package/android/src/main/java/com/adgeist/modules/AdgeistImpl.kt +15 -2
- package/android/src/main/java/com/adgeist/utils/CreativeExtensions.kt +21 -28
- package/android/src/newarch/java/com/Adgeist.kt +1 -2
- package/android/src/newarch/java/com/HTML5AdViewManager.kt +12 -10
- package/android/src/oldarch/java/com/Adgeist.kt +1 -2
- package/android/src/oldarch/java/com/HTML5AdViewManager.kt +12 -10
- package/lib/module/components/HTML5AdView.js +57 -26
- package/lib/module/components/HTML5AdView.js.map +1 -1
- package/lib/module/constants.js +1 -7
- package/lib/module/constants.js.map +1 -1
- package/lib/module/env.js +2 -2
- package/lib/module/env.js.map +1 -1
- package/lib/module/index.js +0 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/specs/HTML5AdNativeComponent.ts +12 -3
- package/lib/module/utilities.js +1 -0
- package/lib/module/utilities.js.map +1 -1
- package/lib/typescript/src/components/HTML5AdView.d.ts.map +1 -1
- package/lib/typescript/src/constants.d.ts +1 -7
- package/lib/typescript/src/constants.d.ts.map +1 -1
- package/lib/typescript/src/env.d.ts +2 -2
- package/lib/typescript/src/env.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +0 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/specs/HTML5AdNativeComponent.d.ts +10 -2
- package/lib/typescript/src/specs/HTML5AdNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/types/FixedAdResponse.d.ts +4 -27
- package/lib/typescript/src/types/FixedAdResponse.d.ts.map +1 -1
- package/lib/typescript/src/types/HTML5AdNativeComponentProps.d.ts +5 -2
- package/lib/typescript/src/types/HTML5AdNativeComponentProps.d.ts.map +1 -1
- package/lib/typescript/src/utilities.d.ts +1 -0
- package/lib/typescript/src/utilities.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/HTML5AdView.tsx +76 -20
- package/src/constants.ts +1 -5
- package/src/env.ts +2 -2
- package/src/index.tsx +0 -2
- package/src/specs/HTML5AdNativeComponent.ts +12 -3
- package/src/types/FixedAdResponse.ts +5 -31
- package/src/types/HTML5AdNativeComponentProps.ts +6 -2
- package/src/utilities.ts +5 -0
- package/lib/module/types/AdType.js +0 -16
- package/lib/module/types/AdType.js.map +0 -1
- package/lib/typescript/src/types/AdType.d.ts +0 -14
- package/lib/typescript/src/types/AdType.d.ts.map +0 -1
- package/src/types/AdType.ts +0 -16
package/README.md
CHANGED
|
@@ -100,8 +100,12 @@ export default function App() {
|
|
|
100
100
|
|
|
101
101
|
Use the `HTML5AdView` component to display banner ads anywhere in your app. Place this component where you want the ads to appear and the SDK will automatically load and render the ad content.
|
|
102
102
|
|
|
103
|
+
An adspace is either **fixed-size** or **responsive**, depending on what you chose while creating it on [adgeist.ai](https://adgeist.ai). Use the snippet below that matches yours. Each one is complete — copy it into your screen and the ad placement is done.
|
|
104
|
+
|
|
105
|
+
**Fixed-size adspace** — you entered a width and a height when you created it:
|
|
106
|
+
|
|
103
107
|
```tsx
|
|
104
|
-
import { HTML5AdView
|
|
108
|
+
import { HTML5AdView } from '@thealteroffice/react-native-adgeist';
|
|
105
109
|
|
|
106
110
|
// Sample Adgeist ad unit ID: 6932a4c022f6786424ce3b84
|
|
107
111
|
// Sample ad size: { width: 320, height: 480 }
|
|
@@ -114,17 +118,15 @@ import { HTML5AdView, AdTypes } from '@thealteroffice/react-native-adgeist';
|
|
|
114
118
|
onAdOpened={}
|
|
115
119
|
onAdClosed={}
|
|
116
120
|
onAdClicked={}
|
|
117
|
-
|
|
121
|
+
onAdWarning={}
|
|
118
122
|
/>;
|
|
119
123
|
```
|
|
120
124
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
Replace `YOUR_AD_WIDTH` and `YOUR_AD_HEIGHT` with the dimensions you mentioned while creating the ad space in the Adgeist web interface. The `adSize` must match those dimensions.
|
|
124
|
-
|
|
125
|
-
**Responsive ads:** For responsive ads, `adSize` is not needed — passing `adIsResponsive={true}` is enough. The ad will automatically size itself to fit the available space.
|
|
125
|
+
**Responsive adspace** — it takes its size from your layout, so it carries no dimensions:
|
|
126
126
|
|
|
127
127
|
```tsx
|
|
128
|
+
import { HTML5AdView } from '@thealteroffice/react-native-adgeist';
|
|
129
|
+
|
|
128
130
|
<HTML5AdView
|
|
129
131
|
adUnitID="YOUR_ADUNIT_ID"
|
|
130
132
|
adIsResponsive={true}
|
|
@@ -133,14 +135,122 @@ Replace `YOUR_AD_WIDTH` and `YOUR_AD_HEIGHT` with the dimensions you mentioned w
|
|
|
133
135
|
onAdOpened={}
|
|
134
136
|
onAdClosed={}
|
|
135
137
|
onAdClicked={}
|
|
136
|
-
|
|
138
|
+
onAdWarning={}
|
|
139
|
+
/>;
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Replace `YOUR_ADUNIT_ID` with your Adgeist Ad Unit ID, as identified in the Adgeist web interface. Each ad placement in your app requires its own ad unit ID.
|
|
143
|
+
|
|
144
|
+
#### What `adSize` actually does
|
|
145
|
+
|
|
146
|
+
`adSize` is the space your layout hands the ad. The component takes that box the moment it mounts, before any ad has been fetched, so your screen is laid out correctly while the request is in flight and nothing jumps when the creative arrives.
|
|
147
|
+
|
|
148
|
+
It is **not** what decides the creative's size. That comes from the adspace you configured on adgeist.ai. When the ad arrives the SDK compares the two:
|
|
149
|
+
|
|
150
|
+
| | What happens |
|
|
151
|
+
|---|---|
|
|
152
|
+
| Your `adSize` matches the adspace | The creative fills the box you reserved. Nothing moves. |
|
|
153
|
+
| They differ | [`onAdWarning`](#ad-events) fires, naming the real size. Change `adSize` to that size. |
|
|
154
|
+
|
|
155
|
+
So replace `YOUR_AD_WIDTH` and `YOUR_AD_HEIGHT` with the exact dimensions you entered on adgeist.ai when you created the adspace, and the two can never disagree.
|
|
156
|
+
|
|
157
|
+
> On React Native your styles own the layout, so the SDK cannot resize the slot on your behalf — it reports the mismatch instead of silently correcting it. Read `onAdWarning` as "your `adSize` is wrong, here is the right one", and treat it as a bug to fix rather than a runtime condition to handle.
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## Extra options
|
|
162
|
+
|
|
163
|
+
The options below are not part of the snippet adgeist.ai gives you. Your ad placement works without them — reach for one only when your layout calls for it.
|
|
164
|
+
|
|
165
|
+
### `reserveSpace` — keep the slot when an ad fails
|
|
166
|
+
|
|
167
|
+
Optional. **Defaults to `true`** — leave it out entirely unless you specifically want `false`.
|
|
168
|
+
|
|
169
|
+
Not every request returns an ad. By default the component holds its box after a failed load, so the rest of your screen stays exactly where it was:
|
|
170
|
+
|
|
171
|
+
```tsx
|
|
172
|
+
import { HTML5AdView } from '@thealteroffice/react-native-adgeist';
|
|
173
|
+
|
|
174
|
+
// Default. Identical to leaving reserveSpace out.
|
|
175
|
+
<HTML5AdView
|
|
176
|
+
adUnitID="YOUR_ADUNIT_ID"
|
|
177
|
+
adSize={{ width: 320, height: 480 }}
|
|
178
|
+
reserveSpace={true}
|
|
179
|
+
/>;
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Pass `false` if you would rather the ad give up its place when there is nothing to show:
|
|
183
|
+
|
|
184
|
+
| `reserveSpace` | After `onAdFailedToLoad` |
|
|
185
|
+
|---|---|
|
|
186
|
+
| `true` (default) | The ad keeps its full box in your layout, empty. No layout shift. |
|
|
187
|
+
| `false` | The ad view detaches itself from your layout. |
|
|
188
|
+
|
|
189
|
+
**Whether there is any space to reserve depends on how the ad is sized:**
|
|
190
|
+
|
|
191
|
+
| Ad | Does reserving work? |
|
|
192
|
+
|---|---|
|
|
193
|
+
| Fixed (`adSize` with both `width` and `height`) | Always. The box has a size of its own to hold, ad or no ad. |
|
|
194
|
+
| Responsive | Only on the axes that actually resolve. An axis that nothing determines measures `0`, and there is no space to hold open. See [Responsive ads and `adSize`](#responsive-ads-and-adsize). |
|
|
195
|
+
|
|
196
|
+
This applies to **failed loads only**. `destroy()` on the component ref always tears the ad down, whatever `reserveSpace` is set to.
|
|
197
|
+
|
|
198
|
+
### Responsive ads and `adSize`
|
|
199
|
+
|
|
200
|
+
Optional. A responsive adspace normally needs no `adSize` at all — that is the point of it. You only reach for this when your layout fixes one axis and leaves the other open.
|
|
201
|
+
|
|
202
|
+
A responsive ad takes each axis independently:
|
|
203
|
+
|
|
204
|
+
| Axis | Where its size comes from |
|
|
205
|
+
|---|---|
|
|
206
|
+
| Named in `adSize` | The value you pass |
|
|
207
|
+
| Left out of `adSize` | The parent — `HTML5AdView` styles that axis `100%` |
|
|
208
|
+
|
|
209
|
+
**Both axes from the parent** — the usual case, no `adSize`:
|
|
210
|
+
|
|
211
|
+
```tsx
|
|
212
|
+
import { View } from 'react-native';
|
|
213
|
+
import { HTML5AdView } from '@thealteroffice/react-native-adgeist';
|
|
214
|
+
|
|
215
|
+
<View style={{ width: 300, height: 250 }}>
|
|
216
|
+
<HTML5AdView adUnitID="YOUR_ADUNIT_ID" adIsResponsive={true} />
|
|
217
|
+
</View>;
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
**One axis from the parent, one from you:**
|
|
221
|
+
|
|
222
|
+
```tsx
|
|
223
|
+
import { HTML5AdView } from '@thealteroffice/react-native-adgeist';
|
|
224
|
+
|
|
225
|
+
// Bottom banner: full width from the parent, you supply the height
|
|
226
|
+
<HTML5AdView
|
|
227
|
+
adUnitID="YOUR_ADUNIT_ID"
|
|
228
|
+
adIsResponsive={true}
|
|
229
|
+
adSize={{ height: 50 }}
|
|
230
|
+
/>;
|
|
231
|
+
|
|
232
|
+
// Side rail: full height from the parent, you supply the width
|
|
233
|
+
<HTML5AdView
|
|
234
|
+
adUnitID="YOUR_ADUNIT_ID"
|
|
235
|
+
adIsResponsive={true}
|
|
236
|
+
adSize={{ width: 120 }}
|
|
137
237
|
/>;
|
|
138
238
|
```
|
|
139
239
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
240
|
+
An axis you leave out becomes `100%`, so it needs an ancestor with a real size on that axis. The case that catches people out is a `ScrollView`: it gives its children no definite height, so a responsive ad inside one should declare `adSize={{ height: ... }}`. Without it the height resolves against a parent that has none, and the ad will not be the size you expected.
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
## Ad events
|
|
245
|
+
|
|
246
|
+
| Callback | Fires when |
|
|
247
|
+
|---|---|
|
|
248
|
+
| `onAdLoaded` | The ad finished loading. |
|
|
249
|
+
| `onAdFailedToLoad` | The request failed. `event.nativeEvent.error` carries the reason. |
|
|
250
|
+
| `onAdOpened` | The ad opened an overlay covering the screen. |
|
|
251
|
+
| `onAdClosed` | The ad was removed from the screen. |
|
|
252
|
+
| `onAdClicked` | The user clicked the ad. |
|
|
253
|
+
| `onAdWarning` | The SDK found a problem that did not stop the ad from loading, but that you should fix. `event.nativeEvent.warning` carries the message, describing the problem and what to change. |
|
|
144
254
|
|
|
145
255
|
|
|
146
256
|
## Support
|
package/android/build.gradle
CHANGED
|
@@ -98,35 +98,14 @@ android {
|
|
|
98
98
|
repositories {
|
|
99
99
|
mavenCentral()
|
|
100
100
|
google()
|
|
101
|
-
/*
|
|
102
|
-
* Alternative: Use local AAR file instead of remote package
|
|
103
|
-
* Uncomment the lines below and comment out the remote dependency above to use a local AAR file.
|
|
104
|
-
* This is useful for testing unreleased versions or when working with custom builds.
|
|
105
|
-
* Place your AAR file in the 'libs' folder.
|
|
106
|
-
*/
|
|
107
|
-
// flatDir {
|
|
108
|
-
// dirs 'libs'
|
|
109
|
-
// }
|
|
110
101
|
}
|
|
111
102
|
|
|
112
103
|
def kotlin_version = getExtOrDefault("kotlinVersion")
|
|
113
104
|
|
|
114
105
|
dependencies {
|
|
115
106
|
implementation "com.facebook.react:react-android"
|
|
116
|
-
implementation "ai.adgeist:adgeistkit:1.1.
|
|
107
|
+
implementation "ai.adgeist:adgeistkit:1.1.34-beta"
|
|
117
108
|
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
|
118
|
-
|
|
119
|
-
/*
|
|
120
|
-
* Alternative: Use local AAR file instead of remote package
|
|
121
|
-
* Uncomment the lines below and comment out the remote dependency above to use a local AAR file.
|
|
122
|
-
* This is useful for testing unreleased versions or when working with custom builds.
|
|
123
|
-
* Place your AAR file in the 'libs' folder.
|
|
124
|
-
*/
|
|
125
|
-
// implementation(name: 'adgeistkit-beta-release', ext: 'aar')
|
|
126
|
-
// implementation "androidx.work:work-runtime-ktx:2.11.1"
|
|
127
|
-
// implementation 'com.google.code.gson:gson:2.10.1'
|
|
128
|
-
// implementation 'com.squareup.okhttp3:okhttp:4.12.0'
|
|
129
|
-
// implementation("com.google.android.gms:play-services-ads-identifier:18.0.1")
|
|
130
109
|
}
|
|
131
110
|
|
|
132
111
|
if (isNewArchitectureEnabled()) {
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
package com.adgeist.components
|
|
2
2
|
|
|
3
3
|
import android.util.Log
|
|
4
|
-
import android.view.View
|
|
5
4
|
import androidx.annotation.RequiresPermission
|
|
6
5
|
import com.adgeistkit.ads.AdListener
|
|
7
6
|
import com.adgeistkit.ads.AdSize
|
|
8
|
-
import com.adgeistkit.ads.AdType
|
|
9
7
|
import com.adgeistkit.ads.AdView
|
|
10
8
|
import com.adgeistkit.request.AdRequest
|
|
9
|
+
import com.adgeistkit.utilities.AdgeistEmbedderApi
|
|
11
10
|
import com.facebook.react.bridge.Arguments
|
|
12
11
|
import com.facebook.react.bridge.ReadableMap
|
|
13
12
|
import com.facebook.react.bridge.WritableMap
|
|
@@ -23,16 +22,20 @@ object HTML5AdViewManagerImpl {
|
|
|
23
22
|
const val EVENT_AD_OPENED = "onAdOpened"
|
|
24
23
|
const val EVENT_AD_CLOSED = "onAdClosed"
|
|
25
24
|
const val EVENT_AD_CLICKED = "onAdClicked"
|
|
25
|
+
const val EVENT_AD_WARNING = "onAdWarning"
|
|
26
|
+
const val EVENT_AD_SIZE_CHANGED = "onAdSizeChanged"
|
|
26
27
|
|
|
27
28
|
private val viewContextMap = mutableMapOf<Int, ThemedReactContext>()
|
|
28
29
|
|
|
30
|
+
@OptIn(AdgeistEmbedderApi::class)
|
|
29
31
|
fun createViewInstance(reactContext: ThemedReactContext): AdView {
|
|
30
32
|
Log.d(TAG, "Creating AdView with ThemedReactContext: ${reactContext.hashCode()}")
|
|
31
|
-
val adView =
|
|
33
|
+
val adView = ReactAdView(reactContext)
|
|
32
34
|
// react-native-screens destroys/recreates the host fragment whenever a
|
|
33
35
|
// screen is covered, so fragment onDestroy is not a teardown signal
|
|
34
36
|
// here; RN drives teardown via onDropViewInstance instead
|
|
35
37
|
adView.watchFragmentLifecycle = false
|
|
38
|
+
adView.isFrameworkHosted = true
|
|
36
39
|
viewContextMap[System.identityHashCode(adView)] = reactContext
|
|
37
40
|
Log.d(TAG, "AdView created with hash: ${System.identityHashCode(adView)} and context hash: ${reactContext.hashCode()}")
|
|
38
41
|
return adView
|
|
@@ -49,30 +52,30 @@ object HTML5AdViewManagerImpl {
|
|
|
49
52
|
}
|
|
50
53
|
|
|
51
54
|
fun setAdSize(view: AdView, adSizeMap: ReadableMap?) {
|
|
52
|
-
if (adSizeMap
|
|
53
|
-
try {
|
|
54
|
-
val width = adSizeMap.getInt("width")
|
|
55
|
-
val height = adSizeMap.getInt("height")
|
|
56
|
-
|
|
57
|
-
val adSize = AdSize(width, height)
|
|
55
|
+
if (adSizeMap == null) return
|
|
58
56
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
57
|
+
try {
|
|
58
|
+
val width = adSizeMap.getDimension("width")
|
|
59
|
+
val height = adSizeMap.getDimension("height")
|
|
60
|
+
|
|
61
|
+
val adSize = when {
|
|
62
|
+
width > 0 && height > 0 -> AdSize(width, height)
|
|
63
|
+
width > 0 -> AdSize.width(width)
|
|
64
|
+
height > 0 -> AdSize.height(height)
|
|
65
|
+
else -> return
|
|
62
66
|
}
|
|
67
|
+
|
|
68
|
+
view.setAdDimension(adSize)
|
|
69
|
+
} catch (e: Exception) {
|
|
70
|
+
Log.e(TAG, "Error setting ad size", e)
|
|
63
71
|
}
|
|
64
72
|
}
|
|
65
73
|
|
|
66
|
-
fun
|
|
67
|
-
|
|
68
|
-
try {
|
|
69
|
-
view.adType = AdType.valueOf(typeToSet)
|
|
70
|
-
} catch (e: IllegalArgumentException) {
|
|
71
|
-
Log.e(TAG, "Invalid ad type: $typeToSet. Must be BANNER, DISPLAY, or COMPANION", e)
|
|
72
|
-
view.adType = AdType.BANNER
|
|
73
|
-
}
|
|
74
|
+
fun setReserveSpace(view: AdView, reserveSpace: Boolean) {
|
|
75
|
+
view.reserveSpace = reserveSpace
|
|
74
76
|
}
|
|
75
77
|
|
|
78
|
+
@OptIn(AdgeistEmbedderApi::class)
|
|
76
79
|
@RequiresPermission("android.permission.INTERNET")
|
|
77
80
|
fun loadAd(view: AdView) {
|
|
78
81
|
try {
|
|
@@ -82,7 +85,6 @@ object HTML5AdViewManagerImpl {
|
|
|
82
85
|
override fun onAdLoaded() {
|
|
83
86
|
view.post {
|
|
84
87
|
sendEvent(view, EVENT_AD_LOADED, Arguments.createMap())
|
|
85
|
-
measureAndLayout(view)
|
|
86
88
|
}
|
|
87
89
|
}
|
|
88
90
|
|
|
@@ -104,6 +106,21 @@ object HTML5AdViewManagerImpl {
|
|
|
104
106
|
override fun onAdClicked() {
|
|
105
107
|
sendEvent(view, EVENT_AD_CLICKED, Arguments.createMap())
|
|
106
108
|
}
|
|
109
|
+
|
|
110
|
+
override fun onAdWarning(warning: String) {
|
|
111
|
+
val event = Arguments.createMap().apply {
|
|
112
|
+
putString("warning", warning)
|
|
113
|
+
}
|
|
114
|
+
sendEvent(view, EVENT_AD_WARNING, event)
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
override fun onAdSizeResolved(adSize: AdSize) {
|
|
118
|
+
val event = Arguments.createMap().apply {
|
|
119
|
+
putDouble("width", adSize.width.toDouble())
|
|
120
|
+
putDouble("height", adSize.height.toDouble())
|
|
121
|
+
}
|
|
122
|
+
sendEvent(view, EVENT_AD_SIZE_CHANGED, event)
|
|
123
|
+
}
|
|
107
124
|
})
|
|
108
125
|
|
|
109
126
|
view.loadAd(adRequest)
|
|
@@ -117,7 +134,7 @@ object HTML5AdViewManagerImpl {
|
|
|
117
134
|
|
|
118
135
|
fun destroyAd(view: AdView) {
|
|
119
136
|
try {
|
|
120
|
-
view.
|
|
137
|
+
view.destroyAd()
|
|
121
138
|
} catch (e: Exception) {
|
|
122
139
|
Log.e(TAG, "Error destroying ad view", e)
|
|
123
140
|
} finally {
|
|
@@ -126,14 +143,6 @@ object HTML5AdViewManagerImpl {
|
|
|
126
143
|
}
|
|
127
144
|
}
|
|
128
145
|
|
|
129
|
-
private fun measureAndLayout(view: AdView) {
|
|
130
|
-
view.measure(
|
|
131
|
-
View.MeasureSpec.makeMeasureSpec(view.width, View.MeasureSpec.EXACTLY),
|
|
132
|
-
View.MeasureSpec.makeMeasureSpec(view.height, View.MeasureSpec.EXACTLY)
|
|
133
|
-
)
|
|
134
|
-
view.layout(view.left, view.top, view.right, view.bottom)
|
|
135
|
-
}
|
|
136
|
-
|
|
137
146
|
private fun sendEvent(view: AdView, eventName: String, params: WritableMap) {
|
|
138
147
|
val reactContext = viewContextMap[System.identityHashCode(view)]
|
|
139
148
|
if (reactContext != null) {
|
|
@@ -148,4 +157,7 @@ object HTML5AdViewManagerImpl {
|
|
|
148
157
|
Log.w(TAG, "Unable to send event $eventName: ThemedReactContext not found or view already destroyed")
|
|
149
158
|
}
|
|
150
159
|
}
|
|
160
|
+
|
|
161
|
+
private fun ReadableMap.getDimension(key: String): Int =
|
|
162
|
+
if (hasKey(key) && !isNull(key)) getDouble(key).toInt() else 0
|
|
151
163
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
package com.adgeist.components
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import com.adgeistkit.ads.AdView
|
|
5
|
+
|
|
6
|
+
class ReactAdView(context: Context) : AdView(context) {
|
|
7
|
+
private val measureAndLayout = Runnable {
|
|
8
|
+
measure(
|
|
9
|
+
MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
|
|
10
|
+
MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)
|
|
11
|
+
)
|
|
12
|
+
layout(left, top, right, bottom)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
override fun requestLayout() {
|
|
16
|
+
super.requestLayout()
|
|
17
|
+
|
|
18
|
+
removeCallbacks(measureAndLayout)
|
|
19
|
+
post(measureAndLayout)
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -14,16 +14,29 @@ import com.adgeistkit.data.network.FetchCreative
|
|
|
14
14
|
import com.facebook.react.bridge.ReadableMap
|
|
15
15
|
import com.adgeist.utils.toWritableMap
|
|
16
16
|
import com.adgeistkit.request.AnalyticsRequest
|
|
17
|
+
import com.adgeistkit.utilities.AdgeistInternalApi
|
|
18
|
+
import com.adgeistkit.utilities.CustomConfig
|
|
17
19
|
|
|
18
20
|
class AdgeistImpl internal constructor(private val context: ReactApplicationContext) {
|
|
19
21
|
private var adgeistInstance: AdgeistCore? = null
|
|
20
22
|
private var getAd: FetchCreative? = null
|
|
21
23
|
private var postCreativeAnalytic: CreativeAnalytics? = null
|
|
22
24
|
|
|
25
|
+
@OptIn(AdgeistInternalApi::class)
|
|
23
26
|
fun initializeSdk(customBidRequestBackendDomain: String?, customPackageOrBundleID: String?, customAdgeistAppID: String?, customVersioning: String?, promise: Promise) {
|
|
24
27
|
try {
|
|
25
28
|
Log.d("AdgeistImpl", "SDK initialized with domain: ${customBidRequestBackendDomain ?: "default"}, package/bundle ID: ${customPackageOrBundleID ?: "default"}, app ID: ${customAdgeistAppID ?: "default"}, versioning: ${customVersioning ?: "default"}")
|
|
26
|
-
|
|
29
|
+
|
|
30
|
+
adgeistInstance = AdgeistCore.initialize(
|
|
31
|
+
context.applicationContext,
|
|
32
|
+
CustomConfig(
|
|
33
|
+
backendDomain = customBidRequestBackendDomain,
|
|
34
|
+
packageOrBundleId = customPackageOrBundleID,
|
|
35
|
+
adgeistAppId = customAdgeistAppID,
|
|
36
|
+
versioning = customVersioning
|
|
37
|
+
)
|
|
38
|
+
)
|
|
39
|
+
|
|
27
40
|
getAd = adgeistInstance?.getCreative()
|
|
28
41
|
postCreativeAnalytic = adgeistInstance?.postCreativeAnalytics()
|
|
29
42
|
promise.resolve("SDK initialized with domain: ${customBidRequestBackendDomain ?: "default"}")
|
|
@@ -38,7 +51,7 @@ class AdgeistImpl internal constructor(private val context: ReactApplicationCont
|
|
|
38
51
|
}
|
|
39
52
|
|
|
40
53
|
fun fetchCreative(adSpaceId: String, buyType: String, promise: Promise) {
|
|
41
|
-
getAd?.fetchCreative(adSpaceId
|
|
54
|
+
getAd?.fetchCreative(adSpaceId) { adData ->
|
|
42
55
|
if (adData.isSuccess && adData.data != null) {
|
|
43
56
|
when (val response = adData.data) {
|
|
44
57
|
is FixedAdResponse -> {
|
|
@@ -11,9 +11,9 @@ fun FixedAdResponse.toWritableMap(): WritableMap {
|
|
|
11
11
|
map.putString("metaData", metaData)
|
|
12
12
|
map.putString("id", id)
|
|
13
13
|
generatedAt?.let { map.putString("generatedAt", it) }
|
|
14
|
-
signature?.let { map.putString("signature", it) }
|
|
15
14
|
campaignId?.let { map.putString("campaignId", it) }
|
|
16
15
|
type?.let { map.putString("type", it) }
|
|
16
|
+
map.putString("adSpaceType", adSpaceType.name.lowercase())
|
|
17
17
|
loadType?.let { map.putString("loadType", it) }
|
|
18
18
|
frontendCacheDurationSeconds?.let { map.putInt("frontendCacheDurationSeconds", it) }
|
|
19
19
|
|
|
@@ -40,25 +40,13 @@ fun FixedAdResponse.toWritableMap(): WritableMap {
|
|
|
40
40
|
cv1Map.putString("ctaUrl", creativeV1.ctaUrl)
|
|
41
41
|
|
|
42
42
|
creativeV1.primary?.let {
|
|
43
|
-
|
|
44
|
-
primMap.putString("type", it.type)
|
|
45
|
-
primMap.putString("fileName", it.fileName)
|
|
46
|
-
primMap.putInt("fileSize", it.fileSize ?: 0)
|
|
47
|
-
primMap.putString("fileUrl", it.fileUrl)
|
|
48
|
-
primMap.putString("thumbnailUrl", it.thumbnailUrl)
|
|
49
|
-
cv1Map.putMap("primary", primMap)
|
|
43
|
+
cv1Map.putMap("primary", it.toWritableMap())
|
|
50
44
|
}
|
|
51
45
|
|
|
52
46
|
creativeV1.companions?.let { companions ->
|
|
53
47
|
val companionsArr = Arguments.createArray()
|
|
54
48
|
companions.forEach { companion ->
|
|
55
|
-
|
|
56
|
-
compMap.putString("type", companion.type)
|
|
57
|
-
compMap.putString("fileName", companion.fileName)
|
|
58
|
-
compMap.putInt("fileSize", companion.fileSize ?: 0)
|
|
59
|
-
compMap.putString("fileUrl", companion.fileUrl)
|
|
60
|
-
compMap.putString("thumbnailUrl", companion.thumbnailUrl)
|
|
61
|
-
companionsArr.pushMap(compMap)
|
|
49
|
+
companionsArr.pushMap(companion.toWritableMap())
|
|
62
50
|
}
|
|
63
51
|
cv1Map.putArray("companions", companionsArr)
|
|
64
52
|
}
|
|
@@ -70,7 +58,7 @@ fun FixedAdResponse.toWritableMap(): WritableMap {
|
|
|
70
58
|
displayOptions?.let { opt ->
|
|
71
59
|
val opMap = Arguments.createMap()
|
|
72
60
|
opMap.putBoolean("isResponsive", opt.isResponsive ?: false)
|
|
73
|
-
opMap.putString("responsiveType",
|
|
61
|
+
opt.responsiveType?.let { opMap.putString("responsiveType", it) }
|
|
74
62
|
|
|
75
63
|
opt.dimensions?.let {
|
|
76
64
|
val dim = Arguments.createMap()
|
|
@@ -86,25 +74,30 @@ fun FixedAdResponse.toWritableMap(): WritableMap {
|
|
|
86
74
|
opMap.putMap("styleOptions", st)
|
|
87
75
|
}
|
|
88
76
|
|
|
89
|
-
opt.
|
|
77
|
+
opt.primaryFormats?.let { list ->
|
|
90
78
|
val arr = Arguments.createArray()
|
|
91
79
|
list.forEach { arr.pushString(it) }
|
|
92
|
-
opMap.putArray("
|
|
80
|
+
opMap.putArray("primaryFormats", arr)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
opt.companionFormats?.let { list ->
|
|
84
|
+
val arr = Arguments.createArray()
|
|
85
|
+
list.forEach { arr.pushString(it) }
|
|
86
|
+
opMap.putArray("companionFormats", arr)
|
|
93
87
|
}
|
|
94
88
|
|
|
95
89
|
map.putMap("displayOptions", opMap)
|
|
96
90
|
}
|
|
97
91
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
it.impressionType?.let { types ->
|
|
101
|
-
val typesArr = Arguments.createArray()
|
|
102
|
-
types.forEach { type -> typesArr.pushString(type) }
|
|
103
|
-
ir.putArray("impressionType", typesArr)
|
|
104
|
-
}
|
|
105
|
-
ir.putInt("minViewDurationSeconds", it.minViewDurationSeconds ?: 0)
|
|
106
|
-
map.putMap("impressionRequirements", ir)
|
|
107
|
-
}
|
|
92
|
+
return map
|
|
93
|
+
}
|
|
108
94
|
|
|
95
|
+
private fun MediaItem.toWritableMap(): WritableMap {
|
|
96
|
+
val map = Arguments.createMap()
|
|
97
|
+
map.putString("type", type)
|
|
98
|
+
map.putString("fileName", fileName)
|
|
99
|
+
map.putInt("fileSize", fileSize ?: 0)
|
|
100
|
+
map.putString("fileUrl", fileUrl)
|
|
101
|
+
map.putString("thumbnailUrl", thumbnailUrl)
|
|
109
102
|
return map
|
|
110
103
|
}
|
|
@@ -43,19 +43,21 @@ class HTML5AdViewManager : SimpleViewManager<AdView>(), HTML5AdNativeComponentMa
|
|
|
43
43
|
HTML5AdViewManagerImpl.setAdSize(view, adSizeMap)
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
@ReactProp(name = "
|
|
47
|
-
override fun
|
|
48
|
-
HTML5AdViewManagerImpl.
|
|
46
|
+
@ReactProp(name = "reserveSpace", defaultBoolean = true)
|
|
47
|
+
override fun setReserveSpace(view: AdView, reserveSpace: Boolean) {
|
|
48
|
+
HTML5AdViewManagerImpl.setReserveSpace(view, reserveSpace)
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
override fun getExportedCustomDirectEventTypeConstants(): Map<String, Any>? {
|
|
52
|
-
return
|
|
53
|
-
HTML5AdViewManagerImpl.EVENT_AD_LOADED,
|
|
54
|
-
HTML5AdViewManagerImpl.EVENT_AD_FAILED_TO_LOAD,
|
|
55
|
-
HTML5AdViewManagerImpl.EVENT_AD_OPENED,
|
|
56
|
-
HTML5AdViewManagerImpl.EVENT_AD_CLOSED,
|
|
57
|
-
HTML5AdViewManagerImpl.EVENT_AD_CLICKED,
|
|
58
|
-
|
|
52
|
+
return listOf(
|
|
53
|
+
HTML5AdViewManagerImpl.EVENT_AD_LOADED,
|
|
54
|
+
HTML5AdViewManagerImpl.EVENT_AD_FAILED_TO_LOAD,
|
|
55
|
+
HTML5AdViewManagerImpl.EVENT_AD_OPENED,
|
|
56
|
+
HTML5AdViewManagerImpl.EVENT_AD_CLOSED,
|
|
57
|
+
HTML5AdViewManagerImpl.EVENT_AD_CLICKED,
|
|
58
|
+
HTML5AdViewManagerImpl.EVENT_AD_WARNING,
|
|
59
|
+
HTML5AdViewManagerImpl.EVENT_AD_SIZE_CHANGED,
|
|
60
|
+
).associateWith { MapBuilder.of("registrationName", it) }
|
|
59
61
|
}
|
|
60
62
|
|
|
61
63
|
@RequiresPermission("android.permission.INTERNET")
|
|
@@ -34,19 +34,21 @@ class HTML5AdViewManager : SimpleViewManager<AdView>() {
|
|
|
34
34
|
HTML5AdViewManagerImpl.setAdSize(view, adSizeMap)
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
@ReactProp(name = "
|
|
38
|
-
fun
|
|
39
|
-
HTML5AdViewManagerImpl.
|
|
37
|
+
@ReactProp(name = "reserveSpace", defaultBoolean = true)
|
|
38
|
+
fun setReserveSpace(view: AdView, reserveSpace: Boolean) {
|
|
39
|
+
HTML5AdViewManagerImpl.setReserveSpace(view, reserveSpace)
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
override fun getExportedCustomDirectEventTypeConstants(): Map<String, Any>? {
|
|
43
|
-
return
|
|
44
|
-
HTML5AdViewManagerImpl.EVENT_AD_LOADED,
|
|
45
|
-
HTML5AdViewManagerImpl.EVENT_AD_FAILED_TO_LOAD,
|
|
46
|
-
HTML5AdViewManagerImpl.EVENT_AD_OPENED,
|
|
47
|
-
HTML5AdViewManagerImpl.EVENT_AD_CLOSED,
|
|
48
|
-
HTML5AdViewManagerImpl.EVENT_AD_CLICKED,
|
|
49
|
-
|
|
43
|
+
return listOf(
|
|
44
|
+
HTML5AdViewManagerImpl.EVENT_AD_LOADED,
|
|
45
|
+
HTML5AdViewManagerImpl.EVENT_AD_FAILED_TO_LOAD,
|
|
46
|
+
HTML5AdViewManagerImpl.EVENT_AD_OPENED,
|
|
47
|
+
HTML5AdViewManagerImpl.EVENT_AD_CLOSED,
|
|
48
|
+
HTML5AdViewManagerImpl.EVENT_AD_CLICKED,
|
|
49
|
+
HTML5AdViewManagerImpl.EVENT_AD_WARNING,
|
|
50
|
+
HTML5AdViewManagerImpl.EVENT_AD_SIZE_CHANGED,
|
|
51
|
+
).associateWith { MapBuilder.of("registrationName", it) }
|
|
50
52
|
}
|
|
51
53
|
|
|
52
54
|
override fun getCommandsMap(): Map<String, Int> {
|