@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.
Files changed (72) hide show
  1. package/android/.project +1 -1
  2. package/android/.settings/org.eclipse.buildship.core.prefs +2 -2
  3. package/android/bin/build.gradle +13 -11
  4. package/android/bin/gradle.properties +4 -4
  5. package/android/build.gradle +19 -81
  6. package/android/gradle.properties +4 -4
  7. package/android/src/main/AndroidManifest.xml +1 -3
  8. package/android/src/main/java/com/adadaptedreactnativesdk/AdadaptedReactNativeSdkModule.kt +39 -54
  9. package/ios/AdadaptedReactNativeSdk.m +1 -1
  10. package/lib/commonjs/api/adadaptedApiRequests.js +3 -3
  11. package/lib/commonjs/api/adadaptedApiRequests.js.map +1 -1
  12. package/lib/commonjs/api/adadaptedApiRequests.mock.js +25 -8
  13. package/lib/commonjs/api/adadaptedApiRequests.mock.js.map +1 -1
  14. package/lib/commonjs/api/adadaptedApiTypes.js +68 -28
  15. package/lib/commonjs/api/adadaptedApiTypes.js.map +1 -1
  16. package/lib/commonjs/components/AdZone.js +101 -67
  17. package/lib/commonjs/components/AdZone.js.map +1 -1
  18. package/lib/commonjs/components/ReportAdButton.js +40 -0
  19. package/lib/commonjs/components/ReportAdButton.js.map +1 -0
  20. package/lib/commonjs/images/ReportIcon.png +0 -0
  21. package/lib/commonjs/index.js +139 -93
  22. package/lib/commonjs/index.js.map +1 -1
  23. package/lib/commonjs/package.json +1 -0
  24. package/lib/commonjs/types.js +4 -0
  25. package/lib/commonjs/types.js.map +1 -1
  26. package/lib/commonjs/util.js +14 -4
  27. package/lib/commonjs/util.js.map +1 -1
  28. package/lib/module/api/adadaptedApiRequests.js +2 -0
  29. package/lib/module/api/adadaptedApiRequests.js.map +1 -1
  30. package/lib/module/api/adadaptedApiRequests.mock.js +27 -9
  31. package/lib/module/api/adadaptedApiRequests.mock.js.map +1 -1
  32. package/lib/module/api/adadaptedApiTypes.js +85 -24
  33. package/lib/module/api/adadaptedApiTypes.js.map +1 -1
  34. package/lib/module/components/AdZone.js +90 -61
  35. package/lib/module/components/AdZone.js.map +1 -1
  36. package/lib/module/components/ReportAdButton.js +34 -0
  37. package/lib/module/components/ReportAdButton.js.map +1 -0
  38. package/lib/module/images/ReportIcon.png +0 -0
  39. package/lib/module/index.js +142 -89
  40. package/lib/module/index.js.map +1 -1
  41. package/lib/module/package.json +1 -0
  42. package/lib/module/types.js +2 -0
  43. package/lib/module/types.js.map +1 -1
  44. package/lib/module/util.js +16 -4
  45. package/lib/module/util.js.map +1 -1
  46. package/lib/typescript/src/api/adadaptedApiRequests.d.ts +1 -0
  47. package/lib/typescript/src/api/adadaptedApiRequests.d.ts.map +1 -0
  48. package/lib/typescript/src/api/adadaptedApiRequests.mock.d.ts +1 -0
  49. package/lib/typescript/src/api/adadaptedApiRequests.mock.d.ts.map +1 -0
  50. package/lib/typescript/src/api/adadaptedApiTypes.d.ts +5 -0
  51. package/lib/typescript/src/api/adadaptedApiTypes.d.ts.map +1 -0
  52. package/lib/typescript/src/components/AdZone.d.ts +11 -6
  53. package/lib/typescript/src/components/AdZone.d.ts.map +1 -0
  54. package/lib/typescript/src/components/ReportAdButton.d.ts +19 -0
  55. package/lib/typescript/src/components/ReportAdButton.d.ts.map +1 -0
  56. package/lib/typescript/src/index.d.ts +33 -17
  57. package/lib/typescript/src/index.d.ts.map +1 -0
  58. package/lib/typescript/src/types.d.ts +3 -2
  59. package/lib/typescript/src/types.d.ts.map +1 -0
  60. package/lib/typescript/src/util.d.ts +13 -0
  61. package/lib/typescript/src/util.d.ts.map +1 -0
  62. package/package.json +151 -155
  63. package/src/api/adadaptedApiRequests.mock.ts +25 -9
  64. package/src/api/adadaptedApiTypes.ts +5 -0
  65. package/src/components/AdZone.tsx +94 -46
  66. package/src/components/ReportAdButton.tsx +46 -0
  67. package/src/images/ReportIcon.png +0 -0
  68. package/src/index.tsx +146 -69
  69. package/src/util.ts +13 -0
  70. package/lib/typescript/example/index.d.ts +0 -1
  71. package/lib/typescript/example/src/App.d.ts +0 -9
  72. package/lib/typescript/jest.setup.d.ts +0 -5
package/src/index.tsx CHANGED
@@ -3,7 +3,6 @@
3
3
  */
4
4
  import * as React from "react";
5
5
  import {
6
- AppState,
7
6
  DeviceEventEmitter,
8
7
  EmitterSubscription,
9
8
  Linking,
@@ -13,7 +12,7 @@ import {
13
12
  import * as adadaptedApiRequests from "./api/adadaptedApiRequests";
14
13
  import {
15
14
  AdSession,
16
- DetailedListItem,
15
+ AdZoneDetailedListItemInfo,
17
16
  KeywordIntercepts,
18
17
  KeywordSearchTerm,
19
18
  ListManagerEvent,
@@ -100,7 +99,7 @@ export enum PayloadApiEnv {
100
99
  }
101
100
 
102
101
  /**
103
- * Interface defining inputs to the {@link Sdk.initialize} method.
102
+ * Interface defining inputs to the {@link Sdk.initialize: AdadaptedReactNativeSdk} method.
104
103
  */
105
104
  export interface InitializeProps {
106
105
  /**
@@ -132,19 +131,19 @@ export interface InitializeProps {
132
131
  onAdZonesRefreshed?(): void;
133
132
  /**
134
133
  * Callback that gets triggered when an "add to list" item/items are clicked.
135
- * @param items - The array of items to "add to list".
134
+ * @param detail - details about the list items to add to cart.
136
135
  */
137
- onAddToListTriggered?(items: DetailedListItem[]): void;
136
+ onAddToListTriggered?(detail: AdZoneDetailedListItemInfo): void;
138
137
  /**
139
138
  * Callback that gets triggered when an "add to list"
140
139
  * occurs by means of an "out of app" data payload.
141
- * @param payloads - All payloads the client must go through.
140
+ * @param detail - Details about payloads clients must go through.
142
141
  */
143
142
  onOutOfAppPayloadAvailable?(payloads: OutOfAppDataPayload[]): void;
144
143
  /**
145
- * Change the optional ad zone visibility default setting.
144
+ * Ad zones that contain off-screen ads.
146
145
  */
147
- defaultToInvisibleAdZone?: boolean;
146
+ offScreenAdZone?: [number];
148
147
  }
149
148
 
150
149
  /**
@@ -220,7 +219,7 @@ export interface AdZoneInfo {
220
219
  /**
221
220
  * The ad zone component.
222
221
  */
223
- adZone: JSX.Element;
222
+ adZone: React.JSX.Element;
224
223
  }
225
224
 
226
225
  /**
@@ -272,6 +271,10 @@ export class AdadaptedReactNativeSdk {
272
271
  * The available ad zones.
273
272
  */
274
273
  private adZones: AdZoneInfo[] | undefined;
274
+ /**
275
+ * The available off-screen ad zones.
276
+ */
277
+ private offScreenAdZones: AdZoneInfo[] = [];
275
278
  /**
276
279
  * The touch sensitivity of the Ad Zone in both the X and Y directions.
277
280
  * This is used to determine the click/press sensitivity when the
@@ -306,11 +309,11 @@ export class AdadaptedReactNativeSdk {
306
309
  /**
307
310
  * If provided, triggers when an "add to list" item is
308
311
  * clicked in an ad zone.
309
- * @param items - The array of items to "add to list".
312
+ * @param detail - The array of items to "add to list".
310
313
  * @param isExternalPayload - If true, the items are from an external payload.
311
314
  */
312
315
  private onAddToListTriggered: (
313
- items: DetailedListItem[],
316
+ detail: AdZoneDetailedListItemInfo,
314
317
  isExternalPayload?: boolean
315
318
  ) => void | undefined;
316
319
  /**
@@ -330,13 +333,9 @@ export class AdadaptedReactNativeSdk {
330
333
  */
331
334
  private AppStateOnEventListener: EmitterSubscription | undefined;
332
335
  /**
333
- * Track ad zone visibility for off-screen ads.
334
- */
335
- private isAdZoneVisible: boolean = true;
336
- /**
337
- * Optional default ad zone visibility for off-screen ads.
336
+ * Ad zones that contain off-screen ads.
338
337
  */
339
- private defaultAdZoneVisibility: boolean | undefined;
338
+ private offScreenAdZone: [number] | undefined;
340
339
  /**
341
340
  * Gets the Session ID.
342
341
  * @returns the Session ID.
@@ -361,6 +360,14 @@ export class AdadaptedReactNativeSdk {
361
360
  return this.adZones;
362
361
  }
363
362
 
363
+ /**
364
+ * Gets the list of available off-screen Ad Zones.
365
+ * @returns all available off-screen ad zones.
366
+ */
367
+ public getOffScreenAdZones(): AdZoneInfo[] | undefined {
368
+ return this.offScreenAdZones;
369
+ }
370
+
364
371
  /**
365
372
  * @inheritDoc
366
373
  */
@@ -423,19 +430,67 @@ export class AdadaptedReactNativeSdk {
423
430
  this.xyAdZoneDragDistanceAllowed || 25
424
431
  }
425
432
  adZoneData={adZones[adZoneId]}
426
- onAddToListTriggered={(items) => {
427
- safeInvoke(this.onAddToListTriggered, items);
433
+ onAddToListTriggered={(details) => {
434
+ safeInvoke(this.onAddToListTriggered, {
435
+ zoneId: adZoneId,
436
+ items: details,
437
+ });
428
438
  }}
429
- isAdZoneVisible={!this.onAdZoneVisibilityChanged}
430
- defaultToInvisibleAdZone={
431
- this.defaultAdZoneVisibility
432
- }
439
+ isAdZoneVisible={true}
440
+ offScreenAdZone={false}
433
441
  />
434
442
  ),
435
443
  });
436
444
  }
437
445
  }
446
+ return adZoneInfoList;
447
+ }
448
+
449
+ /**
450
+ * Creates all off-screen Ad Zone Info objects based on provided off-screen Ad Zones.
451
+ * @param adZones - The object of available zones.
452
+ * @returns the array of off-screen Ad Zone Info objects.
453
+ */
454
+ private generateOffScreenAdZones(adZones: {
455
+ [key: number]: Zone;
456
+ }): AdZoneInfo[] {
457
+ const adZoneInfoList: AdZoneInfo[] = [];
438
458
 
459
+ for (const adZoneId in adZones) {
460
+ if (Object.prototype.hasOwnProperty.call(adZones, adZoneId)) {
461
+ if (
462
+ this.offScreenAdZone &&
463
+ this.offScreenAdZone.length > 0 &&
464
+ this.offScreenAdZone.includes(Number(adZoneId))
465
+ ) {
466
+ adZoneInfoList.push({
467
+ zoneId: adZones[adZoneId].id,
468
+ adZone: (
469
+ <AdZone
470
+ key={adZoneId}
471
+ appId={this.appId}
472
+ sessionId={this.sessionId!}
473
+ udid={this.deviceInfo!.udid}
474
+ deviceOs={this.deviceOs!}
475
+ apiEnv={this.apiEnv}
476
+ xyDragDistanceAllowed={
477
+ this.xyAdZoneDragDistanceAllowed || 25
478
+ }
479
+ adZoneData={adZones[adZoneId]}
480
+ onAddToListTriggered={(items) => {
481
+ safeInvoke(this.onAddToListTriggered, {
482
+ zoneId: adZoneId,
483
+ items,
484
+ });
485
+ }}
486
+ isAdZoneVisible={false}
487
+ offScreenAdZone={true}
488
+ />
489
+ ),
490
+ });
491
+ }
492
+ }
493
+ }
439
494
  return adZoneInfoList;
440
495
  }
441
496
 
@@ -466,6 +521,9 @@ export class AdadaptedReactNativeSdk {
466
521
  .then((response) => {
467
522
  this.sessionInfo = response.data;
468
523
  this.adZones = this.generateAdZones(response.data.zones);
524
+ this.offScreenAdZones = this.generateOffScreenAdZones(
525
+ response.data.zones
526
+ );
469
527
 
470
528
  // Call the user defined callback indicating
471
529
  // the session data has been refreshed.
@@ -576,13 +634,15 @@ export class AdadaptedReactNativeSdk {
576
634
  */
577
635
  private handleDeepLink(event: any): void {
578
636
  const searchStr = "data=";
579
- const dataIndex: number = event["url"].indexOf(searchStr);
637
+ const dataIndex: number = event.url.indexOf(searchStr);
580
638
 
581
639
  if (dataIndex !== -1) {
582
- const encodedData = event.url.substr(dataIndex + searchStr.length);
640
+ const encodedData: string = event.url.substr(
641
+ `${dataIndex}${searchStr.length}`
642
+ );
583
643
  const payloadData = JSON.parse(base64.decode(encodedData));
584
- const payloadId = payloadData["payload_id"];
585
- const itemDataList = payloadData["detailed_list_items"];
644
+ const payloadId = payloadData.payload_id;
645
+ const itemDataList = payloadData.detailed_list_items;
586
646
 
587
647
  if (itemDataList && itemDataList.length > 0) {
588
648
  const finalItemList: OutOfAppDataPayload[] = [];
@@ -592,13 +652,13 @@ export class AdadaptedReactNativeSdk {
592
652
  payload_id: payloadId,
593
653
  detailed_list_items: [
594
654
  {
595
- product_title: itemData["product_title"],
596
- product_brand: itemData["product_brand"],
597
- product_category: itemData["product_category"],
598
- product_barcode: itemData["product_barcode"],
599
- product_discount: itemData["product_discount"],
600
- product_image: itemData["product_image"],
601
- product_sku: itemData["product_sku"],
655
+ product_title: itemData.product_title,
656
+ product_brand: itemData.product_brand,
657
+ product_category: itemData.product_category,
658
+ product_barcode: itemData.product_barcode,
659
+ product_discount: itemData.product_discount,
660
+ product_image: itemData.product_image,
661
+ product_sku: itemData.product_sku,
602
662
  },
603
663
  ],
604
664
  });
@@ -642,16 +702,13 @@ export class AdadaptedReactNativeSdk {
642
702
  payload_id: payload.payload_id,
643
703
  detailed_list_items: [
644
704
  {
645
- product_title: itemData["product_title"],
646
- product_brand: itemData["product_brand"],
647
- product_category:
648
- itemData["product_category"],
649
- product_barcode:
650
- itemData["product_barcode"],
651
- product_discount:
652
- itemData["product_discount"],
653
- product_image: itemData["product_image"],
654
- product_sku: itemData["product_sku"],
705
+ product_title: itemData.product_title,
706
+ product_brand: itemData.product_brand,
707
+ product_category: itemData.product_category,
708
+ product_barcode: itemData.product_barcode,
709
+ product_discount: itemData.product_discount,
710
+ product_image: itemData.product_image,
711
+ product_sku: itemData.product_sku,
655
712
  },
656
713
  ],
657
714
  });
@@ -668,10 +725,9 @@ export class AdadaptedReactNativeSdk {
668
725
 
669
726
  /**
670
727
  * Notify the ad zone of visibility status change for off-screen ads.
728
+ * @param isVisible - Ad Zone visibility tracking.
671
729
  */
672
- public onAdZoneVisibilityChanged(): void {
673
- const isVisible = !this.isAdZoneVisible;
674
- this.isAdZoneVisible = isVisible;
730
+ public onAdZoneVisibilityChanged(isVisible: boolean): void {
675
731
  DeviceEventEmitter.emit("visibility-event", isVisible);
676
732
  }
677
733
 
@@ -735,10 +791,9 @@ export class AdadaptedReactNativeSdk {
735
791
  this.onOutOfAppPayloadAvailable = props.onOutOfAppPayloadAvailable;
736
792
  }
737
793
 
738
- // If provided for off-screen ads, set the ad zone visibility for ad tracking.
739
- if (props.defaultToInvisibleAdZone) {
740
- this.defaultAdZoneVisibility = props.defaultToInvisibleAdZone;
741
- this.onAdZoneVisibilityChanged();
794
+ // If provided set any off-screen ad zones.
795
+ if (props.offScreenAdZone) {
796
+ this.offScreenAdZone = props.offScreenAdZone;
742
797
  }
743
798
 
744
799
  return new Promise<void>((resolve, reject) => {
@@ -796,6 +851,10 @@ export class AdadaptedReactNativeSdk {
796
851
  this.adZones = this.generateAdZones(
797
852
  response.data.zones
798
853
  );
854
+ this.offScreenAdZones =
855
+ this.generateOffScreenAdZones(
856
+ response.data.zones
857
+ );
799
858
 
800
859
  // Start the session data refresh timer.
801
860
  this.onRefreshAdZones();
@@ -821,18 +880,18 @@ export class AdadaptedReactNativeSdk {
821
880
  this.getPayloadItemData();
822
881
 
823
882
  // Initialize an event listener to intercept deep links while the app is running.
824
-
825
- this.deepLinkOnEventListener = Linking.addEventListener(
826
- "url",
827
- this.handleDeepLink
828
- );
829
-
830
- // Initialize an event listener to intercept App state changes.
831
-
832
- this.AppStateOnEventListener = AppState.addEventListener(
833
- "change",
834
- this.handleAppStateChange
835
- );
883
+ this.deepLinkOnEventListener =
884
+ Linking.addEventListener(
885
+ "url",
886
+ this.handleDeepLink
887
+ );
888
+
889
+ // // Initialize an event listener to intercept App state changes.
890
+ // this.AppStateOnEventListener =
891
+ // AppState.addEventListener(
892
+ // "change",
893
+ // this.handleAppStateChange
894
+ // );
836
895
 
837
896
  resolve();
838
897
  })
@@ -858,8 +917,14 @@ export class AdadaptedReactNativeSdk {
858
917
 
859
918
  this.keywordInterceptSearchValue = searchTerm;
860
919
 
861
- if (!this.deviceInfo || !this.sessionId) {
862
- console.error("AdAdapted SDK has not been initialized.");
920
+ if (!this.deviceInfo) {
921
+ console.error(
922
+ "AdAdapted SDK has not been initialized with device info."
923
+ );
924
+ } else if (!this.sessionId) {
925
+ console.error(
926
+ "AdAdapted SDK has not been initialized with session id."
927
+ );
863
928
  } else if (!this.keywordIntercepts) {
864
929
  console.error("No available keyword intercepts.");
865
930
  } else if (
@@ -951,8 +1016,14 @@ export class AdadaptedReactNativeSdk {
951
1016
  public reportKeywordInterceptTermSelected(termId: string): void {
952
1017
  const termObj = this.getKeywordInterceptTerm(termId);
953
1018
 
954
- if (!this.deviceInfo || !this.sessionId) {
955
- console.error("AdAdapted SDK has not been initialized.");
1019
+ if (!this.deviceInfo) {
1020
+ console.error(
1021
+ "AdAdapted SDK has not been initialized with device info."
1022
+ );
1023
+ } else if (!this.sessionId) {
1024
+ console.error(
1025
+ "AdAdapted SDK has not been initialized with session id."
1026
+ );
956
1027
  } else if (!this.keywordIntercepts) {
957
1028
  console.error("No available keyword intercepts.");
958
1029
  } else if (!termId || !termObj) {
@@ -1004,8 +1075,14 @@ export class AdadaptedReactNativeSdk {
1004
1075
  }
1005
1076
  }
1006
1077
 
1007
- if (!this.deviceInfo || !this.sessionId) {
1008
- console.error("AdAdapted SDK has not been initialized.");
1078
+ if (!this.deviceInfo) {
1079
+ console.error(
1080
+ "AdAdapted SDK has not been initialized with device info."
1081
+ );
1082
+ } else if (!this.sessionId) {
1083
+ console.error(
1084
+ "AdAdapted SDK has not been initialized with session id."
1085
+ );
1009
1086
  } else if (!this.keywordIntercepts) {
1010
1087
  console.error("No available keyword intercepts.");
1011
1088
  } else if (!termIds || termIds.length === 0 || termObjs.length === 0) {
package/src/util.ts CHANGED
@@ -14,6 +14,8 @@ export function safeInvoke<R>(func: (() => R) | nil): R | undefined;
14
14
  * See main definition above.
15
15
  * @param func - The function to call.
16
16
  * @param arg1 - Function argument.
17
+ * @returns The return value of the executed function, or undefined if
18
+ * the function is null/undefined
17
19
  */
18
20
  export function safeInvoke<A1, R>(
19
21
  func: ((arg1: A1) => R) | nil,
@@ -24,6 +26,8 @@ export function safeInvoke<A1, R>(
24
26
  * @param func - The function to call.
25
27
  * @param arg1 - Function argument.
26
28
  * @param arg2 - Function argument.
29
+ * @returns The return value of the executed function, or undefined if
30
+ * the function is null/undefined
27
31
  */
28
32
  export function safeInvoke<A1, A2, R>(
29
33
  func: ((arg1: A1, arg2: A2) => R) | nil,
@@ -36,6 +40,8 @@ export function safeInvoke<A1, A2, R>(
36
40
  * @param arg1 - Function argument.
37
41
  * @param arg2 - Function argument.
38
42
  * @param arg3 - Function argument.
43
+ * @returns The return value of the executed function, or undefined if
44
+ * the function is null/undefined
39
45
  */
40
46
  export function safeInvoke<A1, A2, A3, R>(
41
47
  func: ((arg1: A1, arg2: A2, arg3: A3) => R) | nil,
@@ -50,6 +56,8 @@ export function safeInvoke<A1, A2, A3, R>(
50
56
  * @param arg2 - Function argument.
51
57
  * @param arg3 - Function argument.
52
58
  * @param arg4 - Function argument.
59
+ * @returns The return value of the executed function, or undefined if
60
+ * the function is null/undefined
53
61
  */
54
62
  export function safeInvoke<A1, A2, A3, A4, R>(
55
63
  func: ((arg1: A1, arg2: A2, arg3: A3, arg4: A4) => R) | nil,
@@ -66,6 +74,8 @@ export function safeInvoke<A1, A2, A3, A4, R>(
66
74
  * @param arg3 - Function argument.
67
75
  * @param arg4 - Function argument.
68
76
  * @param arg5 - Function argument.
77
+ * @returns The return value of the executed function, or undefined if
78
+ * the function is null/undefined
69
79
  */
70
80
  export function safeInvoke<A1, A2, A3, A4, A5, R>(
71
81
  func: ((arg1: A1, arg2: A2, arg3: A3, arg4: A4, arg5: A5) => R) | nil,
@@ -84,6 +94,8 @@ export function safeInvoke<A1, A2, A3, A4, A5, R>(
84
94
  * @param arg4 - Function argument.
85
95
  * @param arg5 - Function argument.
86
96
  * @param arg6 - Function argument.
97
+ * @returns The return value of the executed function, or undefined if
98
+ * the function is null/undefined
87
99
  */
88
100
  export function safeInvoke<A1, A2, A3, A4, A5, A6, R>(
89
101
  func:
@@ -105,6 +117,7 @@ export function safeInvoke<A1, A2, A3, A4, A5, A6, R>(
105
117
  // eslint-disable-next-line @typescript-eslint/ban-types
106
118
  export function safeInvoke(func: Function | nil, ...args: any[]): any {
107
119
  if (func) {
120
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
108
121
  return func(...args);
109
122
  }
110
123
  }
@@ -1 +0,0 @@
1
- export {};
@@ -1,9 +0,0 @@
1
- /**
2
- * Test app component for testing the
3
- * {@link AdadaptedReactNativeSdk} package/module.
4
- */
5
- import { FC } from "react";
6
- /**
7
- * Creates the main component for the App.
8
- */
9
- export declare const App: FC;
@@ -1,5 +0,0 @@
1
- /**
2
- * Global imports and initialization for Jest unit tests.
3
- * @module
4
- */
5
- import "raf/polyfill";