@adadapted/react-native-sdk 3.2.0 → 3.4.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/android/.project +1 -1
- package/android/.settings/org.eclipse.buildship.core.prefs +2 -2
- package/android/bin/build.gradle +13 -11
- package/android/bin/gradle.properties +4 -4
- package/android/build.gradle +19 -81
- package/android/gradle.properties +4 -4
- package/android/src/main/AndroidManifest.xml +1 -3
- package/android/src/main/java/com/adadaptedreactnativesdk/AdadaptedReactNativeSdkModule.kt +39 -54
- package/ios/AdadaptedReactNativeSdk.m +1 -1
- package/lib/commonjs/api/adadaptedApiRequests.js +3 -3
- package/lib/commonjs/api/adadaptedApiRequests.js.map +1 -1
- package/lib/commonjs/api/adadaptedApiRequests.mock.js +25 -8
- package/lib/commonjs/api/adadaptedApiRequests.mock.js.map +1 -1
- package/lib/commonjs/api/adadaptedApiTypes.js +68 -28
- package/lib/commonjs/api/adadaptedApiTypes.js.map +1 -1
- package/lib/commonjs/components/AdZone.js +101 -67
- package/lib/commonjs/components/AdZone.js.map +1 -1
- package/lib/commonjs/components/ReportAdButton.js +40 -0
- package/lib/commonjs/components/ReportAdButton.js.map +1 -0
- package/lib/commonjs/images/ReportIcon.png +0 -0
- package/lib/commonjs/index.js +139 -93
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/types.js +4 -0
- package/lib/commonjs/types.js.map +1 -1
- package/lib/commonjs/util.js +14 -4
- package/lib/commonjs/util.js.map +1 -1
- package/lib/module/api/adadaptedApiRequests.js +2 -0
- package/lib/module/api/adadaptedApiRequests.js.map +1 -1
- package/lib/module/api/adadaptedApiRequests.mock.js +27 -9
- package/lib/module/api/adadaptedApiRequests.mock.js.map +1 -1
- package/lib/module/api/adadaptedApiTypes.js +85 -24
- package/lib/module/api/adadaptedApiTypes.js.map +1 -1
- package/lib/module/components/AdZone.js +90 -61
- package/lib/module/components/AdZone.js.map +1 -1
- package/lib/module/components/ReportAdButton.js +34 -0
- package/lib/module/components/ReportAdButton.js.map +1 -0
- package/lib/module/images/ReportIcon.png +0 -0
- package/lib/module/index.js +142 -89
- package/lib/module/index.js.map +1 -1
- package/lib/module/package.json +1 -0
- package/lib/module/types.js +2 -0
- package/lib/module/types.js.map +1 -1
- package/lib/module/util.js +16 -4
- package/lib/module/util.js.map +1 -1
- package/lib/typescript/src/api/adadaptedApiRequests.d.ts +1 -0
- package/lib/typescript/src/api/adadaptedApiRequests.d.ts.map +1 -0
- package/lib/typescript/src/api/adadaptedApiRequests.mock.d.ts +1 -0
- package/lib/typescript/src/api/adadaptedApiRequests.mock.d.ts.map +1 -0
- package/lib/typescript/src/api/adadaptedApiTypes.d.ts +5 -0
- package/lib/typescript/src/api/adadaptedApiTypes.d.ts.map +1 -0
- package/lib/typescript/src/components/AdZone.d.ts +11 -6
- package/lib/typescript/src/components/AdZone.d.ts.map +1 -0
- package/lib/typescript/src/components/ReportAdButton.d.ts +19 -0
- package/lib/typescript/src/components/ReportAdButton.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +33 -17
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/types.d.ts +3 -2
- package/lib/typescript/src/types.d.ts.map +1 -0
- package/lib/typescript/src/util.d.ts +13 -0
- package/lib/typescript/src/util.d.ts.map +1 -0
- package/package.json +151 -155
- package/src/api/adadaptedApiRequests.mock.ts +25 -9
- package/src/api/adadaptedApiTypes.ts +5 -0
- package/src/components/AdZone.tsx +94 -46
- package/src/components/ReportAdButton.tsx +46 -0
- package/src/images/ReportIcon.png +0 -0
- package/src/index.tsx +146 -69
- package/src/util.ts +13 -0
- package/lib/typescript/example/index.d.ts +0 -1
- package/lib/typescript/example/src/App.d.ts +0 -9
- package/lib/typescript/jest.setup.d.ts +0 -5
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Component for creating an {@link AdZone}.
|
|
3
3
|
* @module
|
|
4
4
|
*/
|
|
5
|
-
import
|
|
5
|
+
import React, { useEffect, useState } from "react";
|
|
6
6
|
import {
|
|
7
7
|
DeviceEventEmitter,
|
|
8
8
|
Linking,
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
import { WebView } from "react-native-webview";
|
|
22
22
|
import { ApiEnv, DeviceOS } from "../index";
|
|
23
23
|
import { safeInvoke } from "../util";
|
|
24
|
-
import {
|
|
24
|
+
import { ReportAdButton } from "./ReportAdButton";
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
27
|
* Props interface for {@link AdZone}.
|
|
@@ -66,13 +66,13 @@ interface Props {
|
|
|
66
66
|
*/
|
|
67
67
|
onAddToListTriggered?(items: DetailedListItem[]): void;
|
|
68
68
|
/**
|
|
69
|
-
*
|
|
69
|
+
* An ad zone that is not visible on screen for the initial render.
|
|
70
70
|
*/
|
|
71
|
-
|
|
71
|
+
offScreenAdZone: boolean;
|
|
72
72
|
/**
|
|
73
|
-
*
|
|
73
|
+
* Track the ad zone visibility in parent component. (for off-screen ads)
|
|
74
74
|
*/
|
|
75
|
-
|
|
75
|
+
isAdZoneVisible?: boolean;
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
/**
|
|
@@ -101,6 +101,10 @@ interface StyleDef {
|
|
|
101
101
|
* Styles for the WebView element.
|
|
102
102
|
*/
|
|
103
103
|
webView: ViewStyle;
|
|
104
|
+
/**
|
|
105
|
+
* Styles for the ReportAdButton.
|
|
106
|
+
*/
|
|
107
|
+
reportAd: ViewStyle;
|
|
104
108
|
}
|
|
105
109
|
/**
|
|
106
110
|
* Timer used for cycling through ads in the zone
|
|
@@ -113,54 +117,65 @@ let cycleAdTimer: ReturnType<typeof setTimeout> | undefined;
|
|
|
113
117
|
* @param props - properties passed to AdZone.
|
|
114
118
|
* @returns an AdZone JSX Element.
|
|
115
119
|
*/
|
|
116
|
-
export
|
|
117
|
-
// Generates a random number between 0 and (number of available ads - 1).
|
|
118
|
-
const startingAdIndex = Math.floor(
|
|
119
|
-
Math.random() * props.adZoneData.ads.length
|
|
120
|
-
);
|
|
121
|
-
|
|
120
|
+
export const AdZone = (props: Props): React.ReactElement => {
|
|
122
121
|
/**
|
|
123
122
|
* Tracks the current ad index being shown.
|
|
124
123
|
*/
|
|
125
|
-
const [adIndexShown, setAdIndexShown] = useState(
|
|
124
|
+
const [adIndexShown, setAdIndexShown] = useState(
|
|
125
|
+
Math.floor(Math.random() * props.adZoneData.ads.length)
|
|
126
|
+
);
|
|
126
127
|
/**
|
|
127
128
|
* Tracks the coordinates when the user started touching the Ad View.
|
|
128
129
|
*/
|
|
129
|
-
const [touchStartCoords, setTouchStartCoords] = useState({
|
|
130
|
+
const [touchStartCoords, setTouchStartCoords] = useState<TouchCoordinates>({
|
|
131
|
+
x: 0,
|
|
132
|
+
y: 0,
|
|
133
|
+
});
|
|
134
|
+
|
|
130
135
|
/**
|
|
131
136
|
* Track ad visibility (for off-screen ads).
|
|
132
137
|
*/
|
|
133
|
-
const [
|
|
134
|
-
props.defaultToInvisibleAdZone ? false : true
|
|
135
|
-
);
|
|
138
|
+
const [isAdZoneVisible, setIsAdVisibile] = useState(props.isAdZoneVisible);
|
|
136
139
|
|
|
137
|
-
//
|
|
140
|
+
// Setup device listeners.
|
|
138
141
|
useEffect(() => {
|
|
139
|
-
DeviceEventEmitter.addListener("visibility-event", (event) => {
|
|
142
|
+
DeviceEventEmitter.addListener("visibility-event", (event: boolean) => {
|
|
140
143
|
setIsAdVisibile(event);
|
|
141
144
|
});
|
|
142
|
-
|
|
145
|
+
|
|
146
|
+
DeviceEventEmitter.addListener("acknowledge", (itemName: string) => {
|
|
143
147
|
acknowledge(itemName);
|
|
144
148
|
});
|
|
149
|
+
|
|
145
150
|
return () => {
|
|
146
151
|
clearTimeout(cycleAdTimer);
|
|
147
|
-
DeviceEventEmitter.removeAllListeners("visibility-event");
|
|
148
152
|
DeviceEventEmitter.removeAllListeners("acknowledge");
|
|
149
153
|
};
|
|
154
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
150
155
|
}, []);
|
|
151
156
|
|
|
157
|
+
// Send impression on ad cycle.
|
|
152
158
|
useEffect(() => {
|
|
153
159
|
startAdTimer();
|
|
154
|
-
if (
|
|
160
|
+
if (isAdZoneVisible) {
|
|
155
161
|
sendAdImpression();
|
|
156
162
|
}
|
|
163
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
157
164
|
}, [adIndexShown]);
|
|
158
165
|
|
|
159
166
|
useEffect(() => {
|
|
160
|
-
if (
|
|
167
|
+
if (
|
|
168
|
+
props.offScreenAdZone &&
|
|
169
|
+
isAdZoneVisible &&
|
|
170
|
+
props.adZoneData &&
|
|
171
|
+
props.adZoneData.ads &&
|
|
172
|
+
props.adZoneData.ads.length > adIndexShown &&
|
|
173
|
+
!props.adZoneData.ads[adIndexShown].impression_tracked
|
|
174
|
+
) {
|
|
161
175
|
sendAdImpression();
|
|
162
176
|
}
|
|
163
|
-
|
|
177
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
178
|
+
}, [isAdZoneVisible]);
|
|
164
179
|
|
|
165
180
|
/**
|
|
166
181
|
* Generates all component related styles.
|
|
@@ -176,20 +191,26 @@ export function AdZone(props: Props): JSX.Element {
|
|
|
176
191
|
width: "100%",
|
|
177
192
|
height: "100%",
|
|
178
193
|
},
|
|
194
|
+
reportAd: {
|
|
195
|
+
position: "absolute",
|
|
196
|
+
top: 10,
|
|
197
|
+
right: 10,
|
|
198
|
+
},
|
|
179
199
|
});
|
|
180
200
|
}
|
|
181
201
|
|
|
182
202
|
// Generate the styles each render in case the ad is updated with
|
|
183
203
|
// new settings that need to be reflected in the styles of the view.
|
|
184
204
|
const styles = generateStyles();
|
|
185
|
-
const currentAd: Ad | undefined =
|
|
186
|
-
props.adZoneData.ads[adIndexShown] || undefined;
|
|
187
205
|
const finalMainViewStyle = styles.mainView;
|
|
188
206
|
|
|
189
|
-
if (
|
|
207
|
+
if (
|
|
208
|
+
!props.adZoneData.ads[adIndexShown] ||
|
|
209
|
+
!props.adZoneData.ads[adIndexShown].creative_url
|
|
210
|
+
) {
|
|
190
211
|
// If there is no ad to display, make the view take up no space.
|
|
191
|
-
finalMainViewStyle.width =
|
|
192
|
-
finalMainViewStyle.height =
|
|
212
|
+
finalMainViewStyle.width = 0;
|
|
213
|
+
finalMainViewStyle.height = 0;
|
|
193
214
|
}
|
|
194
215
|
|
|
195
216
|
/**
|
|
@@ -225,11 +246,16 @@ export function AdZone(props: Props): JSX.Element {
|
|
|
225
246
|
function acknowledge(itemName: string): void {
|
|
226
247
|
if (props.adZoneData.ads) {
|
|
227
248
|
props.adZoneData.ads.forEach((ad) => {
|
|
228
|
-
ad.
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
249
|
+
if (ad.action_type === "c") {
|
|
250
|
+
ad.payload.detailed_list_items.forEach((item) => {
|
|
251
|
+
if (item.product_title === itemName) {
|
|
252
|
+
triggerReportAdEvent(
|
|
253
|
+
ad,
|
|
254
|
+
ReportedEventType.INTERACTION
|
|
255
|
+
);
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
}
|
|
233
259
|
});
|
|
234
260
|
}
|
|
235
261
|
}
|
|
@@ -273,10 +299,15 @@ export function AdZone(props: Props): JSX.Element {
|
|
|
273
299
|
function startAdTimer(): void {
|
|
274
300
|
clearTimeout(cycleAdTimer);
|
|
275
301
|
|
|
276
|
-
if (
|
|
302
|
+
if (
|
|
303
|
+
props.adZoneData.ads.length > 0 &&
|
|
304
|
+
props.adZoneData.ads[adIndexShown]
|
|
305
|
+
) {
|
|
277
306
|
const refreshTime: number =
|
|
278
307
|
props.adZoneData.ads[adIndexShown].refresh_time * 1000;
|
|
279
308
|
cycleAdTimer = setTimeout(cycleDisplayedAd, refreshTime);
|
|
309
|
+
} else {
|
|
310
|
+
cycleAdTimer = setTimeout(cycleDisplayedAd, 30000);
|
|
280
311
|
}
|
|
281
312
|
}
|
|
282
313
|
|
|
@@ -284,18 +315,18 @@ export function AdZone(props: Props): JSX.Element {
|
|
|
284
315
|
* Cycles to the next ad to display in the current available sequence of ads.
|
|
285
316
|
*/
|
|
286
317
|
function cycleDisplayedAd(): void {
|
|
287
|
-
// Start by determining the next ad index to display.
|
|
288
318
|
let nextAdIndex = 0;
|
|
319
|
+
|
|
320
|
+
// Start by determining the next ad index to display.
|
|
289
321
|
const lastAd = props.adZoneData.ads[adIndexShown];
|
|
290
322
|
|
|
291
323
|
if (adIndexShown < props.adZoneData.ads.length - 1) {
|
|
292
324
|
nextAdIndex = adIndexShown + 1;
|
|
325
|
+
} else {
|
|
326
|
+
nextAdIndex = 0;
|
|
293
327
|
}
|
|
294
328
|
|
|
295
|
-
if (
|
|
296
|
-
// Reset ad impression tracking status.
|
|
297
|
-
lastAd.impression_tracked = false;
|
|
298
|
-
} else {
|
|
329
|
+
if (!lastAd.impression_tracked && !isAdZoneVisible) {
|
|
299
330
|
// Send invisible ad impression if ad was not visible before end of timer cycle.
|
|
300
331
|
triggerReportAdEvent(
|
|
301
332
|
lastAd,
|
|
@@ -303,6 +334,11 @@ export function AdZone(props: Props): JSX.Element {
|
|
|
303
334
|
);
|
|
304
335
|
}
|
|
305
336
|
|
|
337
|
+
if (lastAd.impression_tracked) {
|
|
338
|
+
// Reset ad impression tracking status.
|
|
339
|
+
lastAd.impression_tracked = false;
|
|
340
|
+
}
|
|
341
|
+
|
|
306
342
|
setAdIndexShown(nextAdIndex);
|
|
307
343
|
}
|
|
308
344
|
|
|
@@ -312,8 +348,7 @@ export function AdZone(props: Props): JSX.Element {
|
|
|
312
348
|
function sendAdImpression(): void {
|
|
313
349
|
const ad = props.adZoneData.ads[adIndexShown];
|
|
314
350
|
|
|
315
|
-
|
|
316
|
-
if (!ad.impression_tracked) {
|
|
351
|
+
if (ad.impression_tracked === undefined || !ad.impression_tracked) {
|
|
317
352
|
triggerReportAdEvent(ad, ReportedEventType.IMPRESSION);
|
|
318
353
|
ad.impression_tracked = true;
|
|
319
354
|
}
|
|
@@ -322,10 +357,11 @@ export function AdZone(props: Props): JSX.Element {
|
|
|
322
357
|
// Returned JSX.
|
|
323
358
|
return (
|
|
324
359
|
<View style={finalMainViewStyle}>
|
|
325
|
-
{
|
|
360
|
+
{props.adZoneData.ads[adIndexShown] &&
|
|
361
|
+
props.adZoneData.ads[adIndexShown].creative_url ? (
|
|
326
362
|
<WebView
|
|
327
363
|
source={{
|
|
328
|
-
uri:
|
|
364
|
+
uri: props.adZoneData.ads[adIndexShown].creative_url,
|
|
329
365
|
}}
|
|
330
366
|
androidLayerType="hardware"
|
|
331
367
|
automaticallyAdjustContentInsets={false}
|
|
@@ -351,7 +387,9 @@ export function AdZone(props: Props): JSX.Element {
|
|
|
351
387
|
touchStartCoords.y - touchEndCoords.y
|
|
352
388
|
) < props.xyDragDistanceAllowed
|
|
353
389
|
) {
|
|
354
|
-
onAdZoneSelected(
|
|
390
|
+
onAdZoneSelected(
|
|
391
|
+
props.adZoneData.ads[adIndexShown]
|
|
392
|
+
);
|
|
355
393
|
}
|
|
356
394
|
|
|
357
395
|
// Make sure to reset the start coords
|
|
@@ -360,6 +398,16 @@ export function AdZone(props: Props): JSX.Element {
|
|
|
360
398
|
}}
|
|
361
399
|
/>
|
|
362
400
|
) : undefined}
|
|
401
|
+
<View style={styles.reportAd}>
|
|
402
|
+
{props.adZoneData && props.adZoneData.ads[adIndexShown] ? (
|
|
403
|
+
<ReportAdButton
|
|
404
|
+
adId={props.adZoneData.ads[adIndexShown].ad_id}
|
|
405
|
+
udid={props.udid}
|
|
406
|
+
/>
|
|
407
|
+
) : (
|
|
408
|
+
<></>
|
|
409
|
+
)}
|
|
410
|
+
</View>
|
|
363
411
|
</View>
|
|
364
412
|
);
|
|
365
|
-
}
|
|
413
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import React, { useEffect } from "react";
|
|
2
|
+
import { Image, Linking, StyleSheet, TouchableOpacity } from "react-native";
|
|
3
|
+
|
|
4
|
+
interface Props {
|
|
5
|
+
/**
|
|
6
|
+
* The ad id of the current ad.
|
|
7
|
+
*/
|
|
8
|
+
adId: string;
|
|
9
|
+
/**
|
|
10
|
+
* The current user's udid.
|
|
11
|
+
*/
|
|
12
|
+
udid: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Creates the ReportAdButton component.
|
|
17
|
+
* @param props The component's props.
|
|
18
|
+
* @returns a reportSdButton JSX Element.
|
|
19
|
+
*/
|
|
20
|
+
export function ReportAdButton(props: Props): React.JSX.Element {
|
|
21
|
+
const reportAdUrlBase = new URL("https://feedback.add-it.io/");
|
|
22
|
+
|
|
23
|
+
const styles = StyleSheet.create({
|
|
24
|
+
buttonStyle: {
|
|
25
|
+
width: 14,
|
|
26
|
+
height: 14,
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
reportAdUrlBase.searchParams.append("aid", props.adId);
|
|
32
|
+
reportAdUrlBase.searchParams.append("uid", props.udid);
|
|
33
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
34
|
+
}, [props]);
|
|
35
|
+
|
|
36
|
+
return (
|
|
37
|
+
<TouchableOpacity
|
|
38
|
+
style={styles.buttonStyle}
|
|
39
|
+
onPress={() => {
|
|
40
|
+
Linking.openURL(reportAdUrlBase.toString());
|
|
41
|
+
}}
|
|
42
|
+
>
|
|
43
|
+
<Image source={require("../images/ReportIcon.png")} />
|
|
44
|
+
</TouchableOpacity>
|
|
45
|
+
);
|
|
46
|
+
}
|
|
Binary file
|