react-native-applovin-max 9.0.0 → 9.1.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 (132) hide show
  1. package/android/build.gradle +3 -3
  2. package/android/src/main/java/com/applovin/reactnative/AppLovinMAXAdView.java +1 -1
  3. package/android/src/main/java/com/applovin/reactnative/AppLovinMAXModuleImpl.java +2 -1
  4. package/ios/AppLovinMAX.mm +2 -1
  5. package/lib/commonjs/AdView.js +60 -76
  6. package/lib/commonjs/AdView.js.map +1 -1
  7. package/lib/commonjs/AppLovinMAX.js +43 -29
  8. package/lib/commonjs/AppLovinMAX.js.map +1 -1
  9. package/lib/commonjs/ErrorCode.js +24 -31
  10. package/lib/commonjs/ErrorCode.js.map +1 -1
  11. package/lib/commonjs/EventEmitter.js +22 -1
  12. package/lib/commonjs/EventEmitter.js.map +1 -1
  13. package/lib/commonjs/Utils.js +22 -4
  14. package/lib/commonjs/Utils.js.map +1 -1
  15. package/lib/commonjs/nativeAd/NativeAdView.js +33 -22
  16. package/lib/commonjs/nativeAd/NativeAdView.js.map +1 -1
  17. package/lib/commonjs/nativeAd/NativeAdViewComponents.js +84 -41
  18. package/lib/commonjs/nativeAd/NativeAdViewComponents.js.map +1 -1
  19. package/lib/commonjs/nativeAd/NativeAdViewProvider.js +29 -0
  20. package/lib/commonjs/nativeAd/NativeAdViewProvider.js.map +1 -1
  21. package/lib/commonjs/specs/AppLovinMAXAdViewNativeComponent.js +27 -0
  22. package/lib/commonjs/specs/AppLovinMAXAdViewNativeComponent.js.map +1 -1
  23. package/lib/commonjs/specs/AppLovinMAXNativeAdViewNativeComponent.js +23 -0
  24. package/lib/commonjs/specs/AppLovinMAXNativeAdViewNativeComponent.js.map +1 -1
  25. package/lib/commonjs/specs/NativeAppLovinMAXModule.js +7 -0
  26. package/lib/commonjs/specs/NativeAppLovinMAXModule.js.map +1 -1
  27. package/lib/commonjs/types/AdInfo.js +13 -16
  28. package/lib/commonjs/types/AdInfo.js.map +1 -1
  29. package/lib/module/AdView.js +60 -76
  30. package/lib/module/AdView.js.map +1 -1
  31. package/lib/module/AppLovinMAX.js +44 -29
  32. package/lib/module/AppLovinMAX.js.map +1 -1
  33. package/lib/module/ErrorCode.js +24 -31
  34. package/lib/module/ErrorCode.js.map +1 -1
  35. package/lib/module/EventEmitter.js +22 -1
  36. package/lib/module/EventEmitter.js.map +1 -1
  37. package/lib/module/Utils.js +22 -4
  38. package/lib/module/Utils.js.map +1 -1
  39. package/lib/module/nativeAd/NativeAdView.js +34 -21
  40. package/lib/module/nativeAd/NativeAdView.js.map +1 -1
  41. package/lib/module/nativeAd/NativeAdViewComponents.js +87 -40
  42. package/lib/module/nativeAd/NativeAdViewComponents.js.map +1 -1
  43. package/lib/module/nativeAd/NativeAdViewProvider.js +30 -0
  44. package/lib/module/nativeAd/NativeAdViewProvider.js.map +1 -1
  45. package/lib/module/specs/AppLovinMAXAdViewNativeComponent.js +28 -0
  46. package/lib/module/specs/AppLovinMAXAdViewNativeComponent.js.map +1 -1
  47. package/lib/module/specs/AppLovinMAXNativeAdViewNativeComponent.js +24 -0
  48. package/lib/module/specs/AppLovinMAXNativeAdViewNativeComponent.js.map +1 -1
  49. package/lib/module/specs/NativeAppLovinMAXModule.js +9 -0
  50. package/lib/module/specs/NativeAppLovinMAXModule.js.map +1 -1
  51. package/lib/module/types/AdInfo.js +13 -16
  52. package/lib/module/types/AdInfo.js.map +1 -1
  53. package/lib/typescript/src/AdView.d.ts +27 -21
  54. package/lib/typescript/src/AdView.d.ts.map +1 -1
  55. package/lib/typescript/src/AppLovinMAX.d.ts +22 -21
  56. package/lib/typescript/src/AppLovinMAX.d.ts.map +1 -1
  57. package/lib/typescript/src/ErrorCode.d.ts +24 -31
  58. package/lib/typescript/src/ErrorCode.d.ts.map +1 -1
  59. package/lib/typescript/src/EventEmitter.d.ts +16 -0
  60. package/lib/typescript/src/EventEmitter.d.ts.map +1 -1
  61. package/lib/typescript/src/Utils.d.ts +15 -0
  62. package/lib/typescript/src/Utils.d.ts.map +1 -1
  63. package/lib/typescript/src/nativeAd/NativeAdView.d.ts +15 -7
  64. package/lib/typescript/src/nativeAd/NativeAdView.d.ts.map +1 -1
  65. package/lib/typescript/src/nativeAd/NativeAdViewComponents.d.ts +65 -1
  66. package/lib/typescript/src/nativeAd/NativeAdViewComponents.d.ts.map +1 -1
  67. package/lib/typescript/src/nativeAd/NativeAdViewProvider.d.ts +17 -0
  68. package/lib/typescript/src/nativeAd/NativeAdViewProvider.d.ts.map +1 -1
  69. package/lib/typescript/src/specs/AppLovinMAXAdViewNativeComponent.d.ts +45 -1
  70. package/lib/typescript/src/specs/AppLovinMAXAdViewNativeComponent.d.ts.map +1 -1
  71. package/lib/typescript/src/specs/AppLovinMAXNativeAdViewNativeComponent.d.ts +57 -6
  72. package/lib/typescript/src/specs/AppLovinMAXNativeAdViewNativeComponent.d.ts.map +1 -1
  73. package/lib/typescript/src/specs/NativeAppLovinMAXModule.d.ts +10 -0
  74. package/lib/typescript/src/specs/NativeAppLovinMAXModule.d.ts.map +1 -1
  75. package/lib/typescript/src/types/AdEvent.d.ts +10 -4
  76. package/lib/typescript/src/types/AdEvent.d.ts.map +1 -1
  77. package/lib/typescript/src/types/AdInfo.d.ts +78 -85
  78. package/lib/typescript/src/types/AdInfo.d.ts.map +1 -1
  79. package/lib/typescript/src/types/AdProps.d.ts +14 -15
  80. package/lib/typescript/src/types/AdProps.d.ts.map +1 -1
  81. package/lib/typescript/src/types/AdViewProps.d.ts +28 -29
  82. package/lib/typescript/src/types/AdViewProps.d.ts.map +1 -1
  83. package/lib/typescript/src/types/AppLovinMAX.d.ts +50 -53
  84. package/lib/typescript/src/types/AppLovinMAX.d.ts.map +1 -1
  85. package/lib/typescript/src/types/BannerAd.d.ts +22 -17
  86. package/lib/typescript/src/types/BannerAd.d.ts.map +1 -1
  87. package/lib/typescript/src/types/CMPError.d.ts +7 -4
  88. package/lib/typescript/src/types/CMPError.d.ts.map +1 -1
  89. package/lib/typescript/src/types/Configuration.d.ts +12 -14
  90. package/lib/typescript/src/types/Configuration.d.ts.map +1 -1
  91. package/lib/typescript/src/types/FullscreenAd.d.ts +39 -46
  92. package/lib/typescript/src/types/FullscreenAd.d.ts.map +1 -1
  93. package/lib/typescript/src/types/MRecAd.d.ts +7 -3
  94. package/lib/typescript/src/types/MRecAd.d.ts.map +1 -1
  95. package/lib/typescript/src/types/NativeAd.d.ts +12 -11
  96. package/lib/typescript/src/types/NativeAd.d.ts.map +1 -1
  97. package/lib/typescript/src/types/NativeAdViewProps.d.ts +4 -3
  98. package/lib/typescript/src/types/NativeAdViewProps.d.ts.map +1 -1
  99. package/lib/typescript/src/types/Privacy.d.ts +13 -6
  100. package/lib/typescript/src/types/Privacy.d.ts.map +1 -1
  101. package/lib/typescript/src/types/RewardedAd.d.ts +7 -5
  102. package/lib/typescript/src/types/RewardedAd.d.ts.map +1 -1
  103. package/lib/typescript/src/types/ViewAd.d.ts +46 -50
  104. package/lib/typescript/src/types/ViewAd.d.ts.map +1 -1
  105. package/package.json +1 -1
  106. package/react-native-applovin-max.podspec +2 -2
  107. package/src/AdView.tsx +62 -80
  108. package/src/AppLovinMAX.ts +39 -29
  109. package/src/ErrorCode.ts +24 -31
  110. package/src/EventEmitter.ts +20 -2
  111. package/src/Utils.ts +20 -1
  112. package/src/nativeAd/NativeAdView.tsx +31 -21
  113. package/src/nativeAd/NativeAdViewComponents.tsx +97 -38
  114. package/src/nativeAd/NativeAdViewProvider.tsx +23 -0
  115. package/src/specs/AppLovinMAXAdViewNativeComponent.ts +62 -1
  116. package/src/specs/AppLovinMAXNativeAdViewNativeComponent.ts +70 -6
  117. package/src/specs/NativeAppLovinMAXModule.ts +75 -55
  118. package/src/types/AdEvent.ts +10 -4
  119. package/src/types/AdInfo.ts +78 -85
  120. package/src/types/AdProps.ts +14 -15
  121. package/src/types/AdViewProps.ts +28 -29
  122. package/src/types/AppLovinMAX.ts +50 -53
  123. package/src/types/BannerAd.ts +22 -17
  124. package/src/types/CMPError.ts +7 -4
  125. package/src/types/Configuration.ts +12 -14
  126. package/src/types/FullscreenAd.ts +39 -46
  127. package/src/types/MRecAd.ts +7 -3
  128. package/src/types/NativeAd.ts +12 -11
  129. package/src/types/NativeAdViewProps.ts +4 -3
  130. package/src/types/Privacy.ts +13 -6
  131. package/src/types/RewardedAd.ts +7 -5
  132. package/src/types/ViewAd.ts +46 -50
@@ -2,93 +2,100 @@ import type { AppLovinMAXType } from './types/AppLovinMAX';
2
2
  import type { Configuration } from './types/Configuration';
3
3
  import NativeAppLovinMAX from './specs/NativeAppLovinMAXModule';
4
4
 
5
- const VERSION = '9.0.0';
5
+ const VERSION = '9.1.0';
6
6
 
7
7
  /**
8
- * This enum represents the user's geography used to determine the type of consent flow shown to the
9
- * user.
8
+ * Represents the user's geography, used to determine which type of consent flow to display.
10
9
  */
11
10
  export enum ConsentFlowUserGeography {
12
11
  /**
13
- * User's geography is unknown.
12
+ * The user's geography could not be determined.
14
13
  */
15
14
  UNKNOWN = 'U',
16
15
 
17
16
  /**
18
- * The user is in GDPR region.
17
+ * The user is located in a GDPR region.
19
18
  */
20
19
  GDPR = 'G',
21
20
 
22
21
  /**
23
- * The user is in a non-GDPR region.
22
+ * The user is not in a GDPR region.
24
23
  */
25
24
  OTHER = 'O',
26
25
  }
27
26
 
28
27
  /**
29
- * AppLovin SDK-defined app tracking transparency status values (extended to include "unavailable"
30
- * state on iOS before iOS14).
28
+ * App tracking transparency status values as defined by the AppLovin SDK.
29
+ *
30
+ * These values are based on Apple's AppTrackingTransparency framework (iOS 14+).
31
31
  */
32
32
  export enum AppTrackingStatus {
33
33
  /**
34
- * Device is on iOS before iOS14, AppTrackingTransparency.framework is not available.
34
+ * Device is running an iOS version prior to iOS 14.
35
+ * AppTrackingTransparency is not available.
35
36
  */
36
37
  UNAVAILABLE = 'U',
37
38
 
38
39
  /**
39
- * The user has not yet received an authorization request to authorize access to app-related
40
- * data that can be used for tracking the user or the device.
40
+ * The user has not yet responded to the tracking authorization prompt.
41
41
  */
42
42
  NOT_DETERMINED = 'N',
43
43
 
44
44
  /**
45
- * Authorization to access app-related data that can be used for tracking the user or the device
46
- * is restricted.
45
+ * Tracking is restricted (e.g. due to parental controls).
47
46
  */
48
47
  RESTRICTED = 'R',
49
48
 
50
49
  /**
51
- * The user denies authorization to access app-related data that can be used for tracking the
52
- * user or the device.
50
+ * The user denied authorization for tracking.
53
51
  */
54
52
  DENIED = 'D',
55
53
 
56
54
  /**
57
- * The user authorizes access to app-related data that can be used for tracking the user or the
58
- * device.
55
+ * The user authorized tracking access.
59
56
  */
60
57
  AUTHORIZED = 'A',
61
58
  }
62
59
 
63
60
  /**
64
- * Represents errors for CMP flow.
61
+ * Error codes returned from the Consent Management Platform (CMP) flow.
65
62
  */
66
63
  export enum CMPErrorCode {
67
64
  /**
68
- * Indicates that an unspecified error has occurred.
65
+ * An unspecified error occurred.
69
66
  */
70
67
  UNSPECIFIED = -1,
71
68
 
72
69
  /**
73
- * Indicates that the CMP has not been integrated correctly.
70
+ * The CMP was not integrated correctly.
74
71
  */
75
72
  INTEGRATION_ERROR = 1,
76
73
 
77
74
  /**
78
- * Indicates that the CMP form is unavailable.
75
+ * The CMP form is unavailable.
79
76
  */
80
77
  FORM_UNAVAILABLE = 2,
81
78
 
82
79
  /**
83
- * Indicates that the CMP form is not required.
80
+ * The CMP form is not required for this user.
84
81
  */
85
82
  FORM_NOT_REQUIRED = 3,
86
83
  }
87
84
 
88
- const initialize = (sdkKey: string): Promise<Configuration> => {
89
- return NativeAppLovinMAX.initialize(VERSION, sdkKey);
90
- };
85
+ /**
86
+ * Initializes the AppLovin MAX SDK with the provided SDK key.
87
+ *
88
+ * @param sdkKey - Your AppLovin SDK key.
89
+ * @returns A promise that resolves with the SDK configuration.
90
+ */
91
+ const initialize = (sdkKey: string): Promise<Configuration> => NativeAppLovinMAX.initialize(VERSION, sdkKey);
91
92
 
93
+ /**
94
+ * Retrieves the user segments.
95
+ *
96
+ * @returns A promise resolving to a Map of segment IDs to arrays of group IDs,
97
+ * or `null` if no segments are available.
98
+ */
92
99
  const getSegments = async (): Promise<Map<number, number[]> | null> => {
93
100
  const segments = await NativeAppLovinMAX.getSegments();
94
101
 
@@ -98,10 +105,8 @@ const getSegments = async (): Promise<Map<number, number[]> | null> => {
98
105
 
99
106
  const map = new Map<number, number[]>();
100
107
 
101
- for (const key in segments) {
102
- // Convert the key from a string to a number. In JavaScript, an object cannot have an
103
- // integer as a key, but the Map object can have keys of any data type.
104
- const value = segments[key];
108
+ for (const [key, value] of Object.entries(segments)) {
109
+ // In JavaScript, object keys are always strings, so we convert them to numbers for the Map.
105
110
  if (value) {
106
111
  map.set(Number(key), value);
107
112
  }
@@ -110,10 +115,15 @@ const getSegments = async (): Promise<Map<number, number[]> | null> => {
110
115
  return map;
111
116
  };
112
117
 
118
+ // All native methods except those overridden here
113
119
  type NativeAppLovinMAXType = Omit<AppLovinMAXType, 'initialize' | 'getSegments'>;
114
120
 
115
121
  const nativeMethods: NativeAppLovinMAXType = NativeAppLovinMAX;
116
122
 
123
+ /**
124
+ * Main AppLovin MAX module interface exposed to JavaScript.
125
+ * Wraps the native module and overrides `initialize()` and `getSegments()` for custom handling.
126
+ */
117
127
  export const AppLovinMAX: AppLovinMAXType = Object.create(nativeMethods, {
118
128
  initialize: {
119
129
  value: initialize,
package/src/ErrorCode.ts CHANGED
@@ -16,85 +16,78 @@ const {
16
16
  } = AppLovinMAX.getConstants();
17
17
 
18
18
  /**
19
- * This enum contains various error codes that the SDK can return when a MAX ad fails to load or
20
- * display.
19
+ * Error codes returned by the AppLovin MAX SDK when an ad fails to load or display.
21
20
  */
22
21
  export enum ErrorCode {
23
22
  /**
24
- * This error code represents an error that could not be categorized into one of the other defined
25
- * errors. See the message field in the error object for more details.
23
+ * An unspecified error occurred.
24
+ * See the `message` field for more details.
26
25
  */
27
26
  UNSPECIFIED = MAX_ERROR_CODE_UNSPECIFIED,
28
27
 
29
28
  /**
30
- * This error code indicates that MAX returned no eligible ads from any mediated networks for this
31
- * app/device.
29
+ * No eligible ads were returned from any mediated networks.
32
30
  */
33
31
  NO_FILL = MAX_ERROR_CODE_NO_FILL,
34
32
 
35
33
  /**
36
- * This error code indicates that MAX returned eligible ads from mediated networks, but all ads
37
- * failed to load. See the adLoadFailureInfo field in the error object for more details.
34
+ * Eligible ads were returned but all failed to load.
35
+ * See `adLoadFailureInfo` for more details.
38
36
  */
39
37
  AD_LOAD_FAILED = MAX_ERROR_CODE_AD_LOAD_FAILED,
40
38
 
41
39
  /**
42
- * This error code represents an error that was encountered when showing an ad.
40
+ * An error occurred while attempting to display the ad.
43
41
  */
44
42
  AD_DISPLAY_FAILED = MAX_ERROR_CODE_AD_DISPLAY_FAILED,
45
43
 
46
44
  /**
47
- * This error code indicates that the ad request failed due to a generic network error. See the
48
- * message field in the error object for more details.
45
+ * The ad request failed due to a general network issue.
46
+ * See the `message` field for details.
49
47
  */
50
48
  NETWORK_ERROR = MAX_ERROR_CODE_NETWORK_ERROR,
51
49
 
52
50
  /**
53
- * This error code indicates that the ad request timed out due to a slow internet connection.
51
+ * The ad request timed out, likely due to a slow internet connection.
54
52
  */
55
53
  NETWORK_TIMEOUT = MAX_ERROR_CODE_NETWORK_TIMEOUT,
56
54
 
57
55
  /**
58
- * This error code indicates that the ad request failed because the device is not connected to the
59
- * internet.
56
+ * The ad request failed because the device was offline.
60
57
  */
61
58
  NO_NETWORK = MAX_ERROR_CODE_NO_NETWORK,
62
59
 
63
60
  /**
64
- * This error code indicates that you attempted to show a fullscreen ad while another fullscreen ad
65
- * is still showing.
61
+ * A fullscreen ad was requested while another one was already showing.
66
62
  */
67
63
  FULLSCREEN_AD_ALREADY_SHOWING = MAX_ERROR_CODE_FULLSCREEN_AD_ALREADY_SHOWING,
68
64
 
69
65
  /**
70
- * This error code indicates you are attempting to show a fullscreen ad before the one has been
71
- * loaded.
66
+ * A fullscreen ad was requested before it had finished loading.
72
67
  */
73
68
  FULLSCREEN_AD_NOT_READY = MAX_ERROR_CODE_FULLSCREEN_AD_NOT_READY,
74
69
 
75
70
  /**
76
- * This error code indicates you attempted to present a fullscreen ad from an invalid view
77
- * controller.
78
- * **iOS ONLY**.
71
+ * The ad was presented from an invalid view controller.
72
+ * **iOS only**.
79
73
  */
80
74
  FULLSCREEN_AD_INVALID_VIEW_CONTROLLER = MAX_ERROR_CODE_FULLSCREEN_AD_INVALID_VIEW_CONTROLLER,
81
75
 
82
76
  /**
83
- * This error code indicates that the SDK failed to display an ad because the user has the
84
- * "Don't Keep Activities" developer setting enabled.
85
- * **Android ONLY**.
77
+ * The SDK was unable to display the ad because the
78
+ * "Don't Keep Activities" developer setting is enabled.
79
+ * **Android only**.
86
80
  */
87
81
  DONT_KEEP_ACTIVITIES_ENABLED = MAX_ERROR_CODE_DONT_KEEP_ACTIVITIES_ENABLED,
88
82
 
89
83
  /**
90
- * This error code indicates that the SDK failed to load an ad because the publisher provided an
91
- * invalid ad unit identifier.
84
+ * The ad failed to load due to an invalid ad unit identifier.
92
85
  *
93
- * Possible reasons for an invalid ad unit identifier:
94
- * 1. Ad unit identifier is malformed or does not exist.
95
- * 2. Ad unit is disabled.
96
- * 3. Ad unit is not associated with the current app's package name.
97
- * 4. Ad unit was created within the last 30-60 minutes.
86
+ * Possible causes:
87
+ * 1. The ad unit ID is malformed or does not exist.
88
+ * 2. The ad unit is disabled.
89
+ * 3. The ad unit is not linked to the current apps package name.
90
+ * 4. The ad unit was recently created (less than ~3060 minutes ago).
98
91
  */
99
92
  INVALID_AD_UNIT_ID = MAX_ERROR_CODE_INVALID_AD_UNIT_ID,
100
93
  }
@@ -1,15 +1,28 @@
1
+ /**
2
+ * Manages AppLovin MAX ad event listeners using a shared NativeEventEmitter.
3
+ * Ensures only one active subscription per event type at any given time.
4
+ */
5
+
1
6
  import { NativeEventEmitter } from 'react-native';
2
7
  import type { EventSubscription } from 'react-native';
3
8
  import type { AdEventObject, AdEventListener } from './types/AdEvent';
4
9
  import AppLovinMAX from './specs/NativeAppLovinMAXModule';
5
10
 
6
- // Note that this is a singleton in ES6 module
11
+ // Singleton event emitter for AppLovin MAX native events.
7
12
  const emitter = new NativeEventEmitter(AppLovinMAX);
8
13
 
14
+ // Tracks active subscriptions by event type.
9
15
  const subscriptions: Record<string, EventSubscription> = {};
10
16
 
17
+ /**
18
+ * Subscribes to a specific ad event.
19
+ * If a listener already exists for the event, it will be replaced.
20
+ *
21
+ * @param event - The event name to listen for.
22
+ * @param handler - The callback to handle the event.
23
+ */
11
24
  export const addEventListener = <T extends AdEventObject>(event: string, handler: AdEventListener<T>): void => {
12
- const subscription: EventSubscription = emitter.addListener(event, handler);
25
+ const subscription = emitter.addListener(event, handler);
13
26
  const currentSubscription = subscriptions[event];
14
27
  if (currentSubscription) {
15
28
  currentSubscription.remove();
@@ -17,6 +30,11 @@ export const addEventListener = <T extends AdEventObject>(event: string, handler
17
30
  subscriptions[event] = subscription;
18
31
  };
19
32
 
33
+ /**
34
+ * Unsubscribes from a specific ad event, if a listener exists.
35
+ *
36
+ * @param event - The event name to unsubscribe from.
37
+ */
20
38
  export const removeEventListener = (event: string): void => {
21
39
  const currentSubscription = subscriptions[event];
22
40
  if (currentSubscription) {
package/src/Utils.ts CHANGED
@@ -1,6 +1,17 @@
1
1
  import type { LocalExtraParameterValue } from './types/AdProps';
2
2
 
3
- export const makeExtraParametersArray = (input?: Record<string, string | null>) => (input ? Object.entries(input).map(([key, value]) => ({ key, value })) : []);
3
+ /**
4
+ * Converts a record of string-based extra parameters into an array of `{ key, value }` objects.
5
+ * Used for sending extra parameters to the native SDK.
6
+ *
7
+ * @param input - An optional map of key-value string pairs (or null values).
8
+ * @returns An array of `{ key, value }` objects. Returns an empty array if input is undefined.
9
+ */
10
+ export const makeExtraParametersArray = (input?: Record<string, string | null>): { key: string; value: string | null }[] => {
11
+ if (!input) return [];
12
+
13
+ return Object.entries(input).map(([key, value]) => ({ key, value }));
14
+ };
4
15
 
5
16
  type LocalExtraParameterType = 'str' | 'bool';
6
17
 
@@ -9,6 +20,14 @@ type LocalExtraParameterValueMap = {
9
20
  bool: boolean | null;
10
21
  };
11
22
 
23
+ /**
24
+ * Converts a map of local extra parameters into a filtered array of `{ key, value }` pairs.
25
+ * Only values matching the specified type (`'str'` or `'bool'`) are included.
26
+ *
27
+ * @param input - A record of local extra parameters (string, boolean, or null).
28
+ * @param type - The expected type of each value: `'str'` for strings, `'bool'` for booleans.
29
+ * @returns A filtered array of `{ key, value }` objects, cast to the specified type.
30
+ */
12
31
  export const makeLocalExtraParametersArray = <T extends LocalExtraParameterType>(
13
32
  input: Record<string, LocalExtraParameterValue> | undefined,
14
33
  type: T
@@ -1,3 +1,8 @@
1
+ /**
2
+ * Provides the NativeAdView component, which manages loading and rendering of native ads using the
3
+ * AppLovin MAX SDK in React Native.
4
+ */
5
+
1
6
  import * as React from 'react';
2
7
  import { forwardRef, useContext, useImperativeHandle, useRef, useState, useEffect, useCallback } from 'react';
3
8
  import { findNodeHandle, View } from 'react-native';
@@ -11,8 +16,7 @@ import type { NativeAdViewHandler, NativeAdViewProps } from '../types/NativeAdVi
11
16
  import { makeExtraParametersArray, makeLocalExtraParametersArray } from '../Utils';
12
17
 
13
18
  /**
14
- * The {@link NativeAdView} component that you use building a native ad. This loads a native ad and
15
- * renders it with the asset views:
19
+ * The {@link NativeAdView} component renders a native ad and binds it to asset views:
16
20
  *
17
21
  * - {@link IconView}
18
22
  * - {@link TitleView}
@@ -22,19 +26,21 @@ import { makeExtraParametersArray, makeLocalExtraParametersArray } from '../Util
22
26
  * - {@link MediaView}
23
27
  * - {@link CallToActionView}
24
28
  *
25
- * {@link NativeAdView} fills each asset view with the data of a native ad as soon as it loads the native
26
- * ad, but you need to provide the layout and style of the asset views.
27
- * {@link NativeAdView} can reload a new native ad by using the ref handler.
29
+ * Each asset view must be manually laid out and styled.
30
+ * The component automatically populates content once an ad is loaded.
31
+ * You can reload the ad using the component’s ref via `loadAd()`.
32
+ *
33
+ * **Note:** The AppLovin SDK must be initialized before using this component.
28
34
  *
29
35
  * ### Example:
30
- * ```js
36
+ * ```tsx
31
37
  * <NativeAdView
32
38
  * ref={nativeAdViewHandler}
33
39
  * adUnitId={adUnitId}
34
40
  * style={styles.nativead}
35
41
  * onAdLoaded={(adInfo: AdInfo) => { ... }}
36
42
  * >
37
- * <View style={ ... }>
43
+ * <View style={...}>
38
44
  * <IconView style={styles.icon} />
39
45
  * <TitleView style={styles.title} />
40
46
  * <AdvertiserView style={styles.advertiser} />
@@ -46,6 +52,9 @@ import { makeExtraParametersArray, makeLocalExtraParametersArray } from '../Util
46
52
  * </View>
47
53
  * </NativeAdView>
48
54
  * ```
55
+ *
56
+ * For a complete implementation example, see:
57
+ * https://github.com/AppLovin/AppLovin-MAX-React-Native/blob/master/example/src/NativeAdViewExample.tsx
49
58
  */
50
59
  export const NativeAdView = forwardRef<NativeAdViewHandler, NativeAdViewProps & ViewProps>(function NativeAdView(props, ref) {
51
60
  const [isInitialized, setIsInitialized] = useState<boolean>(false);
@@ -72,21 +81,13 @@ export const NativeAdView = forwardRef<NativeAdViewHandler, NativeAdViewProps &
72
81
  );
73
82
  });
74
83
 
84
+ /**
85
+ * Extracts native ad info from a synthetic event and invokes the provided callback, if any.
86
+ * Ensures optional native ad fields have fallback defaults.
87
+ */
75
88
  const handleNativeAdViewEvent = <T extends AdInfoEvent | AdLoadFailedEvent>(event: NativeSyntheticEvent<T>, callback?: (adInfo: T) => void) => {
76
89
  if (!callback) return;
77
-
78
- let adInfo: any = { ...event.nativeEvent };
79
-
80
- if ('nativeAd' in event.nativeEvent) {
81
- adInfo.nativeAd = {
82
- ...event.nativeEvent.nativeAd,
83
- isIconImageAvailable: event.nativeEvent.nativeAd?.isIconImageAvailable ?? false,
84
- isOptionsViewAvailable: event.nativeEvent.nativeAd?.isOptionsViewAvailable ?? false,
85
- isMediaViewAvailable: event.nativeEvent.nativeAd?.isMediaViewAvailable ?? false,
86
- };
87
- }
88
-
89
- callback(adInfo);
90
+ callback(event.nativeEvent);
90
91
  };
91
92
 
92
93
  const NativeAdViewImpl = forwardRef<NativeAdViewHandler, NativeAdViewProps & ViewProps>(function NativeAdViewImpl(
@@ -98,13 +99,16 @@ const NativeAdViewImpl = forwardRef<NativeAdViewHandler, NativeAdViewProps & Vie
98
99
 
99
100
  const nativeAdViewRef = useRef<React.ElementRef<typeof NativeAdViewComponent> | undefined>();
100
101
 
101
- // Load a new ad
102
+ // Triggers a native ad load via the native command
102
103
  const loadAd = useCallback(() => {
103
104
  nativeAdViewRef.current && Commands.loadAd(nativeAdViewRef.current);
104
105
  }, []);
105
106
 
106
107
  useImperativeHandle(ref, () => ({ loadAd }), [loadAd]);
107
108
 
109
+ /**
110
+ * Updates the native asset view binding for a given view type (e.g., TitleView, MediaView).
111
+ */
108
112
  const updateAssetView = useCallback((assetViewRef: React.RefObject<View>, type: string) => {
109
113
  if (!nativeAdViewRef.current || !assetViewRef.current) return;
110
114
 
@@ -114,6 +118,12 @@ const NativeAdViewImpl = forwardRef<NativeAdViewHandler, NativeAdViewProps & Vie
114
118
  }
115
119
  }, []);
116
120
 
121
+ /**
122
+ * Handles native ad load event:
123
+ * - Updates context with the new native ad data
124
+ * - Notifies native module of updated asset view mappings
125
+ * - Triggers native rendering after all asset views are registered
126
+ */
117
127
  const onAdLoadedEvent = useCallback(
118
128
  (event: NativeSyntheticEvent<AdInfoEvent>) => {
119
129
  const nativeAdImpl = event.nativeEvent.nativeAdImpl;
@@ -1,9 +1,28 @@
1
+ /**
2
+ * Provides pre-styled React Native components for each native ad asset view:
3
+ *
4
+ * - TitleView
5
+ * - AdvertiserView
6
+ * - BodyView
7
+ * - CallToActionView
8
+ * - IconView
9
+ * - OptionsView
10
+ * - MediaView
11
+ * - StarRatingView
12
+ *
13
+ * Each component pulls ad content and view refs from NativeAdView context,
14
+ * and must be rendered inside a {@link NativeAdView}.
15
+ */
16
+
1
17
  import * as React from 'react';
2
18
  import { useContext, useMemo } from 'react';
3
19
  import { Text, Image, View, TouchableOpacity, StyleSheet, Platform } from 'react-native';
4
- import type { ViewProps, ImageProps, TextStyle, TextProps } from 'react-native';
20
+ import type { ViewProps, ImageProps, TextProps } from 'react-native';
5
21
  import { NativeAdViewContext } from './NativeAdViewProvider';
6
22
 
23
+ /**
24
+ * Renders the native ad’s title.
25
+ */
7
26
  export const TitleView = (props: TextProps) => {
8
27
  const { titleRef, nativeAd } = useContext(NativeAdViewContext);
9
28
  return (
@@ -13,6 +32,9 @@ export const TitleView = (props: TextProps) => {
13
32
  );
14
33
  };
15
34
 
35
+ /**
36
+ * Renders the advertiser name.
37
+ */
16
38
  export const AdvertiserView = (props: TextProps) => {
17
39
  const { advertiserRef, nativeAd } = useContext(NativeAdViewContext);
18
40
  return (
@@ -22,6 +44,9 @@ export const AdvertiserView = (props: TextProps) => {
22
44
  );
23
45
  };
24
46
 
47
+ /**
48
+ * Renders the ad’s body text (description).
49
+ */
25
50
  export const BodyView = (props: TextProps) => {
26
51
  const { bodyRef, nativeAd } = useContext(NativeAdViewContext);
27
52
  return (
@@ -31,31 +56,39 @@ export const BodyView = (props: TextProps) => {
31
56
  );
32
57
  };
33
58
 
59
+ /**
60
+ * Renders the call-to-action label.
61
+ * On iOS, wraps the text with a TouchableOpacity for better click behavior.
62
+ */
34
63
  export const CallToActionView = (props: TextProps) => {
35
64
  const { callToActionRef, nativeAd } = useContext(NativeAdViewContext);
36
- // TouchableOpacity disables clicking on certain Android devices.
65
+
37
66
  if (Platform.OS === 'android') {
38
67
  return (
39
68
  <Text {...props} ref={callToActionRef}>
40
69
  {nativeAd.callToAction ?? ''}
41
70
  </Text>
42
71
  );
43
- } else {
44
- return (
45
- <TouchableOpacity>
46
- <Text {...props} ref={callToActionRef}>
47
- {nativeAd.callToAction ?? ''}
48
- </Text>
49
- </TouchableOpacity>
50
- );
51
72
  }
73
+
74
+ return (
75
+ <TouchableOpacity>
76
+ <Text {...props} ref={callToActionRef}>
77
+ {nativeAd.callToAction ?? ''}
78
+ </Text>
79
+ </TouchableOpacity>
80
+ );
52
81
  };
53
82
 
83
+ /**
84
+ * Renders the icon image for the native ad.
85
+ * Falls back to a blank placeholder if not available.
86
+ */
54
87
  export const IconView = (props: Omit<ImageProps, 'source'>) => {
55
88
  const { imageRef, nativeAd } = useContext(NativeAdViewContext);
56
89
  const defaultIcon = require('./img/blank_icon.png');
57
90
 
58
- const imageSource = (() => {
91
+ const imageSource = useMemo(() => {
59
92
  if (nativeAd?.url) {
60
93
  return { uri: nativeAd.url };
61
94
  }
@@ -63,60 +96,86 @@ export const IconView = (props: Omit<ImageProps, 'source'>) => {
63
96
  return { uri: `data:image/jpeg;base64,${nativeAd.imageSource}` };
64
97
  }
65
98
  return defaultIcon;
66
- })();
99
+ }, [nativeAd.url, nativeAd.imageSource, defaultIcon]);
67
100
 
68
101
  return <Image {...props} ref={imageRef} source={imageSource} />;
69
102
  };
70
103
 
104
+ /**
105
+ * Renders the native ad’s options view.
106
+ */
71
107
  export const OptionsView = (props: ViewProps) => {
72
108
  const { optionViewRef } = useContext(NativeAdViewContext);
73
109
  return <View {...props} ref={optionViewRef} />;
74
110
  };
75
111
 
112
+ /**
113
+ * Renders the native ad’s media content.
114
+ */
76
115
  export const MediaView = (props: ViewProps) => {
77
116
  const { mediaViewRef } = useContext(NativeAdViewContext);
78
117
  return <View {...props} ref={mediaViewRef} />;
79
118
  };
80
119
 
81
- export const StarRatingView = (props: ViewProps) => {
82
- const { style, ...restProps } = props;
83
- const maxStarCount = 5;
84
- const starTextStyle = useMemo(() => StyleSheet.flatten(style) as TextStyle, [style]);
85
- const starColor = starTextStyle.color ?? '#ffe234';
86
- const starSize = starTextStyle.fontSize ?? 10;
120
+ /**
121
+ * Props for the {@link StarRatingView} component, which displays a star rating
122
+ * using Unicode stars (★ and ☆) styled with color, shadow, and size.
123
+ */
124
+ type StarRatingViewProps = ViewProps & {
125
+ /**
126
+ * The color used for filled (active) stars.
127
+ * Defaults to gold (#ffe234).
128
+ */
129
+ color?: string;
130
+
131
+ /**
132
+ * The color used for empty (inactive) stars.
133
+ * Defaults to light gray (#dedede).
134
+ */
135
+ shadowColor?: string;
136
+
137
+ /**
138
+ * The size of each star, which also determines their visual size.
139
+ * Defaults to 10.
140
+ */
141
+ size?: number;
142
+ };
143
+
144
+ /**
145
+ * Renders the star rating of the ad, using Unicode stars (★ and ☆).
146
+ * Filled stars are rendered over hollow stars using a clipped view.
147
+ */
148
+ export const StarRatingView = ({ color = '#ffe234', shadowColor = '#dedede', size = 10, style }: StarRatingViewProps) => {
87
149
  const { nativeAd } = useContext(NativeAdViewContext);
150
+ const maxStarCount = 5;
151
+
152
+ const containerStyle = useMemo(() => StyleSheet.flatten([style, styles.starRatingContainer]), [style]);
88
153
 
89
- // Memoize the star rendering process
90
154
  const stars = useMemo(() => {
91
- if (!nativeAd.starRating) {
92
- return Array.from({ length: maxStarCount }).map((_, index) => (
93
- <Text key={index} style={{ fontSize: starSize }}>
94
- {' '}
95
- </Text>
96
- ));
97
- }
155
+ const starRating = Math.max(0, Math.min(maxStarCount, nativeAd.starRating ?? 0));
98
156
 
99
157
  return Array.from({ length: maxStarCount }).map((_, index) => {
100
- const starRating = nativeAd.starRating!;
101
- const width = (starRating - index) * starSize;
158
+ const isFull = starRating > index;
159
+ const width = Math.min(size, Math.max(0, (starRating - index) * size));
160
+
102
161
  return (
103
162
  <View key={index}>
104
- <Text style={{ fontSize: starSize, color: starColor }}>{String.fromCodePoint(0x2606)}</Text>
105
- {starRating > index && (
106
- <View style={[{ width: width }, styles.starRating]}>
107
- <Text style={{ fontSize: starSize, color: starColor }}>{String.fromCodePoint(0x2605)}</Text>
163
+ <Text style={{ fontSize: size, color: isFull ? color : shadowColor }}>{String.fromCodePoint(0x2606)}</Text>
164
+ {isFull && (
165
+ <View style={[{ width }, styles.starRating]}>
166
+ <Text style={{ fontSize: size, color }}>{String.fromCodePoint(0x2605)}</Text>
108
167
  </View>
109
168
  )}
110
169
  </View>
111
170
  );
112
171
  });
113
- }, [nativeAd.starRating, starColor, starSize]);
172
+ }, [nativeAd.starRating, color, shadowColor, size]);
114
173
 
115
- return (
116
- <View {...restProps} style={[style, styles.starRatingContainer]}>
117
- {stars}
118
- </View>
119
- );
174
+ if (!nativeAd.starRating) {
175
+ return <View style={containerStyle} />;
176
+ }
177
+
178
+ return <View style={containerStyle}>{stars}</View>;
120
179
  };
121
180
 
122
181
  const styles = StyleSheet.create({