react-native-applovin-max 8.2.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 (196) hide show
  1. package/android/build.gradle +14 -3
  2. package/android/src/main/java/com/applovin/reactnative/AppLovinMAXAdView.java +34 -27
  3. package/android/src/main/java/com/applovin/reactnative/AppLovinMAXAdViewManagerImpl.java +110 -0
  4. package/android/src/main/java/com/applovin/reactnative/AppLovinMAXAdViewUiComponent.java +15 -13
  5. package/android/src/main/java/com/applovin/reactnative/{AppLovinMAXModule.java → AppLovinMAXModuleImpl.java} +108 -168
  6. package/android/src/main/java/com/applovin/reactnative/AppLovinMAXNativeAdView.java +84 -56
  7. package/android/src/main/java/com/applovin/reactnative/AppLovinMAXNativeAdViewManagerImpl.java +101 -0
  8. package/android/src/main/java/com/applovin/reactnative/AppLovinMAXPackage.java +44 -11
  9. package/android/src/main/java/com/applovin/reactnative/AppLovinMAXUtils.java +56 -0
  10. package/android/src/newarch/com/applovin/reactnative/AppLovinMAXAdViewManager.java +151 -0
  11. package/android/src/newarch/com/applovin/reactnative/AppLovinMAXModule.java +453 -0
  12. package/android/src/newarch/com/applovin/reactnative/AppLovinMAXNativeAdViewManager.java +130 -0
  13. package/android/src/oldarch/com/applovin/reactnative/AppLovinMAXAdViewManager.java +128 -0
  14. package/android/src/oldarch/com/applovin/reactnative/AppLovinMAXModule.java +453 -0
  15. package/android/src/oldarch/com/applovin/reactnative/AppLovinMAXNativeAdViewManager.java +93 -0
  16. package/ios/AppLovinMAX.h +8 -3
  17. package/ios/{AppLovinMAX.m → AppLovinMAX.mm} +67 -53
  18. package/ios/AppLovinMAXAdView.h +7 -2
  19. package/ios/AppLovinMAXAdView.mm +747 -0
  20. package/ios/{AppLovinMAXAdViewManager.m → AppLovinMAXAdViewManager.mm} +3 -2
  21. package/ios/{AppLovinMAXAdViewUIComponent.m → AppLovinMAXAdViewUIComponent.mm} +2 -1
  22. package/ios/AppLovinMAXNativeAdView.h +15 -4
  23. package/ios/AppLovinMAXNativeAdView.mm +745 -0
  24. package/ios/AppLovinMAXNativeAdViewManager.mm +116 -0
  25. package/lib/commonjs/AdView.js +102 -142
  26. package/lib/commonjs/AdView.js.map +1 -1
  27. package/lib/commonjs/AppLovinMAX.js +49 -34
  28. package/lib/commonjs/AppLovinMAX.js.map +1 -1
  29. package/lib/commonjs/AppOpenAd.js +8 -10
  30. package/lib/commonjs/AppOpenAd.js.map +1 -1
  31. package/lib/commonjs/BannerAd.js +19 -21
  32. package/lib/commonjs/BannerAd.js.map +1 -1
  33. package/lib/commonjs/ErrorCode.js +27 -36
  34. package/lib/commonjs/ErrorCode.js.map +1 -1
  35. package/lib/commonjs/EventEmitter.js +24 -5
  36. package/lib/commonjs/EventEmitter.js.map +1 -1
  37. package/lib/commonjs/InterstitialAd.js +8 -10
  38. package/lib/commonjs/InterstitialAd.js.map +1 -1
  39. package/lib/commonjs/MRecAd.js +14 -16
  40. package/lib/commonjs/MRecAd.js.map +1 -1
  41. package/lib/commonjs/Privacy.js +3 -5
  42. package/lib/commonjs/Privacy.js.map +1 -1
  43. package/lib/commonjs/RewardedAd.js +8 -10
  44. package/lib/commonjs/RewardedAd.js.map +1 -1
  45. package/lib/commonjs/Utils.js +43 -0
  46. package/lib/commonjs/Utils.js.map +1 -0
  47. package/lib/commonjs/nativeAd/NativeAdView.js +84 -50
  48. package/lib/commonjs/nativeAd/NativeAdView.js.map +1 -1
  49. package/lib/commonjs/nativeAd/NativeAdViewComponents.js +129 -82
  50. package/lib/commonjs/nativeAd/NativeAdViewComponents.js.map +1 -1
  51. package/lib/commonjs/nativeAd/NativeAdViewProvider.js +67 -8
  52. package/lib/commonjs/nativeAd/NativeAdViewProvider.js.map +1 -1
  53. package/lib/commonjs/nativeAd/img/blank_icon.png +0 -0
  54. package/lib/commonjs/specs/AppLovinMAXAdViewNativeComponent.js +41 -0
  55. package/lib/commonjs/specs/AppLovinMAXAdViewNativeComponent.js.map +1 -0
  56. package/lib/commonjs/specs/AppLovinMAXNativeAdViewNativeComponent.js +37 -0
  57. package/lib/commonjs/specs/AppLovinMAXNativeAdViewNativeComponent.js.map +1 -0
  58. package/lib/commonjs/specs/NativeAppLovinMAXModule.js +16 -0
  59. package/lib/commonjs/specs/NativeAppLovinMAXModule.js.map +1 -0
  60. package/lib/commonjs/types/AdInfo.js +13 -16
  61. package/lib/commonjs/types/AdInfo.js.map +1 -1
  62. package/lib/module/AdView.js +98 -139
  63. package/lib/module/AdView.js.map +1 -1
  64. package/lib/module/AppLovinMAX.js +47 -32
  65. package/lib/module/AppLovinMAX.js.map +1 -1
  66. package/lib/module/AppOpenAd.js +1 -4
  67. package/lib/module/AppOpenAd.js.map +1 -1
  68. package/lib/module/BannerAd.js +1 -4
  69. package/lib/module/BannerAd.js.map +1 -1
  70. package/lib/module/ErrorCode.js +25 -35
  71. package/lib/module/ErrorCode.js.map +1 -1
  72. package/lib/module/EventEmitter.js +24 -5
  73. package/lib/module/EventEmitter.js.map +1 -1
  74. package/lib/module/InterstitialAd.js +2 -5
  75. package/lib/module/InterstitialAd.js.map +1 -1
  76. package/lib/module/MRecAd.js +1 -4
  77. package/lib/module/MRecAd.js.map +1 -1
  78. package/lib/module/Privacy.js +1 -4
  79. package/lib/module/Privacy.js.map +1 -1
  80. package/lib/module/RewardedAd.js +2 -5
  81. package/lib/module/RewardedAd.js.map +1 -1
  82. package/lib/module/Utils.js +35 -0
  83. package/lib/module/Utils.js.map +1 -0
  84. package/lib/module/nativeAd/NativeAdView.js +83 -47
  85. package/lib/module/nativeAd/NativeAdView.js.map +1 -1
  86. package/lib/module/nativeAd/NativeAdViewComponents.js +134 -83
  87. package/lib/module/nativeAd/NativeAdViewComponents.js.map +1 -1
  88. package/lib/module/nativeAd/NativeAdViewProvider.js +69 -9
  89. package/lib/module/nativeAd/NativeAdViewProvider.js.map +1 -1
  90. package/lib/module/nativeAd/img/blank_icon.png +0 -0
  91. package/lib/module/specs/AppLovinMAXAdViewNativeComponent.js +35 -0
  92. package/lib/module/specs/AppLovinMAXAdViewNativeComponent.js.map +1 -0
  93. package/lib/module/specs/AppLovinMAXNativeAdViewNativeComponent.js +31 -0
  94. package/lib/module/specs/AppLovinMAXNativeAdViewNativeComponent.js.map +1 -0
  95. package/lib/module/specs/NativeAppLovinMAXModule.js +12 -0
  96. package/lib/module/specs/NativeAppLovinMAXModule.js.map +1 -0
  97. package/lib/module/types/AdInfo.js +13 -16
  98. package/lib/module/types/AdInfo.js.map +1 -1
  99. package/lib/typescript/src/AdView.d.ts +38 -32
  100. package/lib/typescript/src/AdView.d.ts.map +1 -1
  101. package/lib/typescript/src/AppLovinMAX.d.ts +22 -21
  102. package/lib/typescript/src/AppLovinMAX.d.ts.map +1 -1
  103. package/lib/typescript/src/AppOpenAd.d.ts.map +1 -1
  104. package/lib/typescript/src/BannerAd.d.ts.map +1 -1
  105. package/lib/typescript/src/ErrorCode.d.ts +24 -31
  106. package/lib/typescript/src/ErrorCode.d.ts.map +1 -1
  107. package/lib/typescript/src/EventEmitter.d.ts +16 -0
  108. package/lib/typescript/src/EventEmitter.d.ts.map +1 -1
  109. package/lib/typescript/src/InterstitialAd.d.ts.map +1 -1
  110. package/lib/typescript/src/MRecAd.d.ts.map +1 -1
  111. package/lib/typescript/src/Privacy.d.ts.map +1 -1
  112. package/lib/typescript/src/RewardedAd.d.ts.map +1 -1
  113. package/lib/typescript/src/Utils.d.ts +31 -0
  114. package/lib/typescript/src/Utils.d.ts.map +1 -0
  115. package/lib/typescript/src/nativeAd/NativeAdView.d.ts +15 -7
  116. package/lib/typescript/src/nativeAd/NativeAdView.d.ts.map +1 -1
  117. package/lib/typescript/src/nativeAd/NativeAdViewComponents.d.ts +65 -1
  118. package/lib/typescript/src/nativeAd/NativeAdViewComponents.d.ts.map +1 -1
  119. package/lib/typescript/src/nativeAd/NativeAdViewProvider.d.ts +31 -5
  120. package/lib/typescript/src/nativeAd/NativeAdViewProvider.d.ts.map +1 -1
  121. package/lib/typescript/src/specs/AppLovinMAXAdViewNativeComponent.d.ts +130 -0
  122. package/lib/typescript/src/specs/AppLovinMAXAdViewNativeComponent.d.ts.map +1 -0
  123. package/lib/typescript/src/specs/AppLovinMAXNativeAdViewNativeComponent.d.ts +131 -0
  124. package/lib/typescript/src/specs/AppLovinMAXNativeAdViewNativeComponent.d.ts.map +1 -0
  125. package/lib/typescript/src/specs/NativeAppLovinMAXModule.d.ts +142 -0
  126. package/lib/typescript/src/specs/NativeAppLovinMAXModule.d.ts.map +1 -0
  127. package/lib/typescript/src/types/AdEvent.d.ts +10 -4
  128. package/lib/typescript/src/types/AdEvent.d.ts.map +1 -1
  129. package/lib/typescript/src/types/AdInfo.d.ts +79 -86
  130. package/lib/typescript/src/types/AdInfo.d.ts.map +1 -1
  131. package/lib/typescript/src/types/AdProps.d.ts +16 -17
  132. package/lib/typescript/src/types/AdProps.d.ts.map +1 -1
  133. package/lib/typescript/src/types/AdViewProps.d.ts +28 -29
  134. package/lib/typescript/src/types/AdViewProps.d.ts.map +1 -1
  135. package/lib/typescript/src/types/AppLovinMAX.d.ts +50 -53
  136. package/lib/typescript/src/types/AppLovinMAX.d.ts.map +1 -1
  137. package/lib/typescript/src/types/BannerAd.d.ts +22 -17
  138. package/lib/typescript/src/types/BannerAd.d.ts.map +1 -1
  139. package/lib/typescript/src/types/CMPError.d.ts +7 -4
  140. package/lib/typescript/src/types/CMPError.d.ts.map +1 -1
  141. package/lib/typescript/src/types/Configuration.d.ts +12 -14
  142. package/lib/typescript/src/types/Configuration.d.ts.map +1 -1
  143. package/lib/typescript/src/types/FullscreenAd.d.ts +39 -46
  144. package/lib/typescript/src/types/FullscreenAd.d.ts.map +1 -1
  145. package/lib/typescript/src/types/MRecAd.d.ts +7 -3
  146. package/lib/typescript/src/types/MRecAd.d.ts.map +1 -1
  147. package/lib/typescript/src/types/NativeAd.d.ts +15 -10
  148. package/lib/typescript/src/types/NativeAd.d.ts.map +1 -1
  149. package/lib/typescript/src/types/NativeAdViewProps.d.ts +4 -3
  150. package/lib/typescript/src/types/NativeAdViewProps.d.ts.map +1 -1
  151. package/lib/typescript/src/types/Privacy.d.ts +13 -6
  152. package/lib/typescript/src/types/Privacy.d.ts.map +1 -1
  153. package/lib/typescript/src/types/RewardedAd.d.ts +7 -5
  154. package/lib/typescript/src/types/RewardedAd.d.ts.map +1 -1
  155. package/lib/typescript/src/types/ViewAd.d.ts +46 -50
  156. package/lib/typescript/src/types/ViewAd.d.ts.map +1 -1
  157. package/package.json +9 -1
  158. package/react-native-applovin-max.podspec +3 -3
  159. package/src/AdView.tsx +100 -183
  160. package/src/AppLovinMAX.ts +42 -33
  161. package/src/AppOpenAd.ts +1 -3
  162. package/src/BannerAd.ts +1 -3
  163. package/src/ErrorCode.ts +25 -34
  164. package/src/EventEmitter.ts +22 -5
  165. package/src/InterstitialAd.ts +2 -4
  166. package/src/MRecAd.ts +1 -3
  167. package/src/Privacy.ts +1 -3
  168. package/src/RewardedAd.ts +2 -4
  169. package/src/Utils.ts +45 -0
  170. package/src/nativeAd/NativeAdView.tsx +83 -73
  171. package/src/nativeAd/NativeAdViewComponents.tsx +120 -89
  172. package/src/nativeAd/NativeAdViewProvider.tsx +60 -12
  173. package/src/nativeAd/img/blank_icon.png +0 -0
  174. package/src/specs/AppLovinMAXAdViewNativeComponent.ts +157 -0
  175. package/src/specs/AppLovinMAXNativeAdViewNativeComponent.ts +153 -0
  176. package/src/specs/NativeAppLovinMAXModule.ts +228 -0
  177. package/src/types/AdEvent.ts +10 -4
  178. package/src/types/AdInfo.ts +79 -86
  179. package/src/types/AdProps.ts +16 -17
  180. package/src/types/AdViewProps.ts +28 -29
  181. package/src/types/AppLovinMAX.ts +50 -53
  182. package/src/types/BannerAd.ts +22 -17
  183. package/src/types/CMPError.ts +7 -4
  184. package/src/types/Configuration.ts +12 -14
  185. package/src/types/FullscreenAd.ts +39 -46
  186. package/src/types/MRecAd.ts +7 -3
  187. package/src/types/NativeAd.ts +16 -10
  188. package/src/types/NativeAdViewProps.ts +4 -3
  189. package/src/types/Privacy.ts +13 -6
  190. package/src/types/RewardedAd.ts +7 -5
  191. package/src/types/ViewAd.ts +46 -50
  192. package/android/src/main/java/com/applovin/reactnative/AppLovinMAXAdViewManager.java +0 -149
  193. package/android/src/main/java/com/applovin/reactnative/AppLovinMAXNativeAdViewManager.java +0 -163
  194. package/ios/AppLovinMAXAdView.m +0 -325
  195. package/ios/AppLovinMAXNativeAdView.m +0 -432
  196. package/ios/AppLovinMAXNativeAdViewManager.m +0 -64
@@ -1,150 +1,181 @@
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
- import { useContext, useRef, useEffect, useCallback, useMemo } from 'react';
3
- import { findNodeHandle, Text, Image, View, TouchableOpacity, StyleSheet, Platform } from 'react-native';
4
- import type { ViewProps, ImageProps, TextStyle, StyleProp, TextProps } from 'react-native';
18
+ import { useContext, useMemo } from 'react';
19
+ import { Text, Image, View, TouchableOpacity, StyleSheet, Platform } from 'react-native';
20
+ import type { ViewProps, ImageProps, TextProps } from 'react-native';
5
21
  import { NativeAdViewContext } from './NativeAdViewProvider';
6
- import type { NativeAd } from '../types/NativeAd';
7
-
8
- // Custom hook to handle setting native ad view properties and return nativeAd
9
- const useNativeAdViewProps = (nativeAdProp: keyof NativeAd, ref: React.RefObject<any>, nativePropKey: string) => {
10
- const { nativeAd, nativeAdView } = useContext(NativeAdViewContext);
11
-
12
- const setNativeProps = useCallback(() => {
13
- if (!nativeAd[nativeAdProp] || !ref.current) return;
14
- nativeAdView?.setNativeProps({
15
- [nativePropKey]: findNodeHandle(ref.current),
16
- });
17
- }, [nativeAd, nativeAdProp, nativeAdView, ref, nativePropKey]);
18
-
19
- useEffect(() => {
20
- setNativeProps();
21
- }, [setNativeProps]);
22
-
23
- return nativeAd;
24
- };
25
22
 
23
+ /**
24
+ * Renders the native ad’s title.
25
+ */
26
26
  export const TitleView = (props: TextProps) => {
27
- const titleRef = useRef<Text | null>(null);
28
- const nativeAd = useNativeAdViewProps('title', titleRef, 'titleView');
29
-
27
+ const { titleRef, nativeAd } = useContext(NativeAdViewContext);
30
28
  return (
31
29
  <Text {...props} ref={titleRef}>
32
- {nativeAd.title || null}
30
+ {nativeAd.title ?? ''}
33
31
  </Text>
34
32
  );
35
33
  };
36
34
 
35
+ /**
36
+ * Renders the advertiser name.
37
+ */
37
38
  export const AdvertiserView = (props: TextProps) => {
38
- const advertiserRef = useRef<Text | null>(null);
39
- const nativeAd = useNativeAdViewProps('advertiser', advertiserRef, 'advertiserView');
40
-
39
+ const { advertiserRef, nativeAd } = useContext(NativeAdViewContext);
41
40
  return (
42
41
  <Text {...props} ref={advertiserRef}>
43
- {nativeAd.advertiser || null}
42
+ {nativeAd.advertiser ?? ''}
44
43
  </Text>
45
44
  );
46
45
  };
47
46
 
47
+ /**
48
+ * Renders the ad’s body text (description).
49
+ */
48
50
  export const BodyView = (props: TextProps) => {
49
- const bodyRef = useRef<Text | null>(null);
50
- const nativeAd = useNativeAdViewProps('body', bodyRef, 'bodyView');
51
-
51
+ const { bodyRef, nativeAd } = useContext(NativeAdViewContext);
52
52
  return (
53
53
  <Text {...props} ref={bodyRef}>
54
- {nativeAd.body || null}
54
+ {nativeAd.body ?? ''}
55
55
  </Text>
56
56
  );
57
57
  };
58
58
 
59
+ /**
60
+ * Renders the call-to-action label.
61
+ * On iOS, wraps the text with a TouchableOpacity for better click behavior.
62
+ */
59
63
  export const CallToActionView = (props: TextProps) => {
60
- const callToActionRef = useRef<Text | null>(null);
61
- const nativeAd = useNativeAdViewProps('callToAction', callToActionRef, 'callToActionView');
64
+ const { callToActionRef, nativeAd } = useContext(NativeAdViewContext);
62
65
 
63
- // TouchableOpacity disables clicking on certain Android devices.
64
66
  if (Platform.OS === 'android') {
65
67
  return (
66
68
  <Text {...props} ref={callToActionRef}>
67
- {nativeAd.callToAction || null}
69
+ {nativeAd.callToAction ?? ''}
68
70
  </Text>
69
71
  );
70
- } else {
71
- return (
72
- <TouchableOpacity>
73
- <Text {...props} ref={callToActionRef}>
74
- {nativeAd.callToAction || null}
75
- </Text>
76
- </TouchableOpacity>
77
- );
78
72
  }
73
+
74
+ return (
75
+ <TouchableOpacity>
76
+ <Text {...props} ref={callToActionRef}>
77
+ {nativeAd.callToAction ?? ''}
78
+ </Text>
79
+ </TouchableOpacity>
80
+ );
79
81
  };
80
82
 
83
+ /**
84
+ * Renders the icon image for the native ad.
85
+ * Falls back to a blank placeholder if not available.
86
+ */
81
87
  export const IconView = (props: Omit<ImageProps, 'source'>) => {
82
- const imageRef = useRef<Image | null>(null);
83
- const nativeAd = useNativeAdViewProps('image', imageRef, 'iconView');
84
-
85
- return nativeAd.url ? (
86
- <Image {...props} ref={imageRef} source={{ uri: nativeAd.url }} />
87
- ) : nativeAd.image ? (
88
- <Image {...props} ref={imageRef} source={0} />
89
- ) : (
90
- <View {...props} />
91
- );
88
+ const { imageRef, nativeAd } = useContext(NativeAdViewContext);
89
+ const defaultIcon = require('./img/blank_icon.png');
90
+
91
+ const imageSource = useMemo(() => {
92
+ if (nativeAd?.url) {
93
+ return { uri: nativeAd.url };
94
+ }
95
+ if (nativeAd?.imageSource) {
96
+ return { uri: `data:image/jpeg;base64,${nativeAd.imageSource}` };
97
+ }
98
+ return defaultIcon;
99
+ }, [nativeAd.url, nativeAd.imageSource, defaultIcon]);
100
+
101
+ return <Image {...props} ref={imageRef} source={imageSource} />;
92
102
  };
93
103
 
104
+ /**
105
+ * Renders the native ad’s options view.
106
+ */
94
107
  export const OptionsView = (props: ViewProps) => {
95
- const viewRef = useRef<View | null>(null);
96
- useNativeAdViewProps('isOptionsViewAvailable', viewRef, 'optionsView');
97
-
98
- return <View {...props} ref={viewRef} />;
108
+ const { optionViewRef } = useContext(NativeAdViewContext);
109
+ return <View {...props} ref={optionViewRef} />;
99
110
  };
100
111
 
112
+ /**
113
+ * Renders the native ad’s media content.
114
+ */
101
115
  export const MediaView = (props: ViewProps) => {
102
- const viewRef = useRef<View | null>(null);
103
- useNativeAdViewProps('isMediaViewAvailable', viewRef, 'mediaView');
104
-
105
- return <View {...props} ref={viewRef} />;
116
+ const { mediaViewRef } = useContext(NativeAdViewContext);
117
+ return <View {...props} ref={mediaViewRef} />;
106
118
  };
107
119
 
108
- export const StarRatingView = (props: ViewProps) => {
109
- const { style, ...restProps } = props;
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
+ };
110
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) => {
149
+ const { nativeAd } = useContext(NativeAdViewContext);
111
150
  const maxStarCount = 5;
112
- const starColor = StyleSheet.flatten((style as StyleProp<TextStyle>) || {}).color ?? '#ffe234';
113
- const starSize = StyleSheet.flatten((style as StyleProp<TextStyle>) || {}).fontSize ?? 10;
114
151
 
115
- const { nativeAd } = useContext(NativeAdViewContext);
152
+ const containerStyle = useMemo(() => StyleSheet.flatten([style, styles.starRatingContainer]), [style]);
116
153
 
117
- // Memoize the star rendering process
118
154
  const stars = useMemo(() => {
119
- if (!nativeAd.starRating) {
120
- return Array.from({ length: maxStarCount }).map((_, index) => (
121
- <Text key={index} style={{ fontSize: starSize }}>
122
- {' '}
123
- </Text>
124
- ));
125
- }
155
+ const starRating = Math.max(0, Math.min(maxStarCount, nativeAd.starRating ?? 0));
126
156
 
127
157
  return Array.from({ length: maxStarCount }).map((_, index) => {
128
- const starRating = nativeAd.starRating!;
129
- const width = (starRating - index) * starSize;
158
+ const isFull = starRating > index;
159
+ const width = Math.min(size, Math.max(0, (starRating - index) * size));
160
+
130
161
  return (
131
162
  <View key={index}>
132
- <Text style={{ fontSize: starSize, color: starColor }}>{String.fromCodePoint(0x2606)}</Text>
133
- {starRating > index && (
134
- <View style={[{ width: width }, styles.starRating]}>
135
- <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>
136
167
  </View>
137
168
  )}
138
169
  </View>
139
170
  );
140
171
  });
141
- }, [nativeAd.starRating, starColor, starSize]);
172
+ }, [nativeAd.starRating, color, shadowColor, size]);
142
173
 
143
- return (
144
- <View {...restProps} style={[style, styles.starRatingContainer]}>
145
- {stars}
146
- </View>
147
- );
174
+ if (!nativeAd.starRating) {
175
+ return <View style={containerStyle} />;
176
+ }
177
+
178
+ return <View style={containerStyle}>{stars}</View>;
148
179
  };
149
180
 
150
181
  const styles = StyleSheet.create({
@@ -1,43 +1,91 @@
1
+ /**
2
+ * Provides context and state management for NativeAdView and its child asset views.
3
+ * Shares asset view refs and native ad data between internal components and the native SDK.
4
+ */
5
+
1
6
  import * as React from 'react';
2
- import { useState, createContext } from 'react';
7
+ import { useState, createContext, useRef } from 'react';
3
8
  import type { ReactNode } from 'react';
4
- import type { NativeMethods } from 'react-native';
9
+ import type { Image, NativeMethods, Text, View } from 'react-native';
5
10
  import type { NativeAd } from '../types/NativeAd';
6
- import type { NativeAdViewProps } from '../types/NativeAdViewProps';
11
+ import type { NativeProps } from '../specs/AppLovinMAXNativeAdViewNativeComponent';
12
+
13
+ /**
14
+ * Native component type for the rendered NativeAdView.
15
+ */
16
+ export type NativeAdViewType = React.Component<NativeProps> & NativeMethods;
7
17
 
8
- export type NativeAdViewType = React.Component<NativeAdViewProps> & NativeMethods;
18
+ // Ref types for native views
19
+ type TextRef = React.ElementRef<typeof Text>;
20
+ type ImageRef = React.ElementRef<typeof Image>;
21
+ type ViewRef = React.ElementRef<typeof View>;
9
22
 
23
+ /**
24
+ * Context type used internally by NativeAdView.
25
+ * Stores references to asset views and the current native ad data.
26
+ */
10
27
  export type NativeAdViewContextType = {
28
+ titleRef: React.RefObject<TextRef>;
29
+ advertiserRef: React.RefObject<TextRef>;
30
+ bodyRef: React.RefObject<TextRef>;
31
+ callToActionRef: React.RefObject<TextRef>;
32
+ imageRef: React.RefObject<ImageRef>;
33
+ optionViewRef: React.RefObject<ViewRef>;
34
+ mediaViewRef: React.RefObject<ViewRef>;
11
35
  nativeAd: NativeAd;
12
- nativeAdView: NativeAdViewType | null;
13
36
  setNativeAd: React.Dispatch<React.SetStateAction<NativeAd>>;
14
- setNativeAdView: React.Dispatch<React.SetStateAction<NativeAdViewType | null>>;
15
37
  };
16
38
 
39
+ // Default for an uninitialized native ad
17
40
  const defaultNativeAd: NativeAd = {
18
41
  isOptionsViewAvailable: false,
19
42
  isMediaViewAvailable: false,
20
43
  };
21
44
 
45
+ /**
46
+ * Internal context used by NativeAdView to provide access to asset view refs and native ad data.
47
+ */
22
48
  export const NativeAdViewContext = createContext<NativeAdViewContextType>({
49
+ titleRef: { current: null },
50
+ advertiserRef: { current: null },
51
+ bodyRef: { current: null },
52
+ callToActionRef: { current: null },
53
+ imageRef: { current: null },
54
+ optionViewRef: { current: null },
55
+ mediaViewRef: { current: null },
23
56
  nativeAd: defaultNativeAd,
24
- nativeAdView: null,
25
57
  setNativeAd: () => {},
26
- setNativeAdView: () => {},
27
58
  });
28
59
 
60
+ /**
61
+ * React provider that wraps components requiring access to NativeAdViewContext.
62
+ */
29
63
  export const NativeAdViewProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
64
+ const titleRef = useRef<TextRef | null>(null);
65
+ const advertiserRef = useRef<TextRef | null>(null);
66
+ const bodyRef = useRef<TextRef | null>(null);
67
+ const callToActionRef = useRef<TextRef | null>(null);
68
+ const imageRef = useRef<ImageRef | null>(null);
69
+ const optionViewRef = useRef<ViewRef | null>(null);
70
+ const mediaViewRef = useRef<ViewRef | null>(null);
30
71
  const [nativeAd, setNativeAd] = useState<NativeAd>(defaultNativeAd);
31
- const [nativeAdView, setNativeAdView] = useState<NativeAdViewType | null>(null);
32
72
 
73
+ /**
74
+ * Memoized context value to avoid unnecessary renders.
75
+ */
33
76
  const providerValue = React.useMemo(
34
77
  () => ({
78
+ titleRef,
79
+ advertiserRef,
80
+ bodyRef,
81
+ callToActionRef,
82
+ imageRef,
83
+ optionViewRef,
84
+ mediaViewRef,
35
85
  nativeAd,
36
- nativeAdView,
37
86
  setNativeAd,
38
- setNativeAdView,
39
87
  }),
40
- [nativeAd, nativeAdView]
88
+ [nativeAd]
41
89
  );
42
90
 
43
91
  return <NativeAdViewContext.Provider value={providerValue}>{children}</NativeAdViewContext.Provider>;
Binary file
@@ -0,0 +1,157 @@
1
+ import type { HostComponent, ViewProps } from 'react-native';
2
+ import type { Double, DirectEventHandler, WithDefault } from 'react-native/Libraries/Types/CodegenTypes';
3
+ import codegenNativeCommands from 'react-native/Libraries/Utilities/codegenNativeCommands';
4
+ import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
5
+
6
+ /**
7
+ * Payload for ad lifecycle events (e.g. load, display, click).
8
+ */
9
+ export type AdInfoEvent = Readonly<{
10
+ adUnitId: string;
11
+ adFormat: string;
12
+ adViewId?: Double;
13
+ networkName: string;
14
+ networkPlacement: string;
15
+ creativeId?: string | null;
16
+ placement?: string | null;
17
+ revenue: Double;
18
+ revenuePrecision: string;
19
+ latencyMillis: Double;
20
+ dspName?: string | null;
21
+ size: Readonly<{
22
+ width: Double;
23
+ height: Double;
24
+ }>;
25
+ }>;
26
+
27
+ /**
28
+ * Payload for ad load failure events.
29
+ */
30
+ export type AdLoadFailedEvent = Readonly<{
31
+ adUnitId: string;
32
+ adViewId?: Double;
33
+ code: Double;
34
+ message?: string | null;
35
+ mediatedNetworkErrorCode: Double;
36
+ mediatedNetworkErrorMessage: string;
37
+ adLoadFailureInfo?: string | null;
38
+ }>;
39
+
40
+ /**
41
+ * Payload for ad display failure events.
42
+ */
43
+ export type AdDisplayFailedEvent = Readonly<{
44
+ adUnitId: string;
45
+ adFormat: string;
46
+ adViewId?: Double;
47
+ networkName: string;
48
+ networkPlacement: string;
49
+ creativeId?: string | null;
50
+ placement?: string | null;
51
+ revenue: Double;
52
+ revenuePrecision: string;
53
+ latencyMillis: Double;
54
+ dspName?: string | null;
55
+ size: Readonly<{
56
+ width: Double;
57
+ height: Double;
58
+ }>;
59
+ code: Double;
60
+ message?: string | null;
61
+ mediatedNetworkErrorCode: Double;
62
+ mediatedNetworkErrorMessage: string;
63
+ }>;
64
+
65
+ /**
66
+ * Props passed to the {@link AppLovinMAXAdView} native component.
67
+ */
68
+ export interface NativeProps extends ViewProps {
69
+ /** Ad unit ID used to load the ad. */
70
+ adUnitId: string;
71
+
72
+ /** Ad format (e.g., "BANNER", "MREC"). */
73
+ adFormat?: string;
74
+
75
+ /** Unique identifier for this ad view. Defaults to 0. */
76
+ adViewId?: WithDefault<Double, 0>;
77
+
78
+ /** Optional placement name for ad tracking. */
79
+ placement?: string | null;
80
+
81
+ /** Optional custom data associated with the ad. */
82
+ customData?: string | null;
83
+
84
+ /** Enables adaptive banner sizing. Defaults to `true`. */
85
+ adaptiveBannerEnabled?: WithDefault<boolean, true>;
86
+
87
+ /** Enables automatic refresh of the ad. Defaults to `true`. */
88
+ autoRefresh?: WithDefault<boolean, true>;
89
+
90
+ /** Whether to automatically load the ad on mount. Defaults to `true`. */
91
+ loadOnMount?: WithDefault<boolean, true>;
92
+
93
+ /** Extra key-value string parameters passed to the SDK. */
94
+ extraParameters?: ReadonlyArray<{
95
+ key: string;
96
+ value: string | null;
97
+ }>;
98
+
99
+ /** Local string parameters passed to the mediation adapter. */
100
+ strLocalExtraParameters?: ReadonlyArray<{
101
+ key: string;
102
+ value: string | null;
103
+ }>;
104
+
105
+ /** Local boolean parameters passed to the mediation adapter. */
106
+ boolLocalExtraParameters?: ReadonlyArray<{
107
+ key: string;
108
+ value: boolean | null;
109
+ }>;
110
+
111
+ /** Called when an ad is successfully loaded. */
112
+ onAdLoadedEvent: DirectEventHandler<AdInfoEvent>;
113
+
114
+ /** Called when an ad fails to load. */
115
+ onAdLoadFailedEvent: DirectEventHandler<AdLoadFailedEvent>;
116
+
117
+ /** Called when an ad fails to display. */
118
+ onAdDisplayFailedEvent: DirectEventHandler<AdDisplayFailedEvent>;
119
+
120
+ /** Called when the ad is clicked. */
121
+ onAdClickedEvent: DirectEventHandler<AdInfoEvent>;
122
+
123
+ /** Called when the ad expands. */
124
+ onAdExpandedEvent: DirectEventHandler<AdInfoEvent>;
125
+
126
+ /** Called when the ad collapses. */
127
+ onAdCollapsedEvent: DirectEventHandler<AdInfoEvent>;
128
+
129
+ /** Called when ad revenue is reported. */
130
+ onAdRevenuePaidEvent: DirectEventHandler<AdInfoEvent>;
131
+ }
132
+
133
+ type AppLovinMAXAdViewNativeComponentType = HostComponent<NativeProps>;
134
+
135
+ /**
136
+ * Native commands callable from JS for managing {@link AppLovinMAXAdView}.
137
+ */
138
+ interface NativeCommands {
139
+ /**
140
+ * Manually starts loading a new ad when `loadOnMount` is `false`.
141
+ *
142
+ * @param viewRef - Reference to the native ad view component.
143
+ */
144
+ loadAd(viewRef: React.ElementRef<AppLovinMAXAdViewNativeComponentType>): void;
145
+ }
146
+
147
+ /**
148
+ * JS interface to ad view commands for {@link AppLovinMAXAdView}.
149
+ */
150
+ export const Commands: NativeCommands = codegenNativeCommands<NativeCommands>({
151
+ supportedCommands: ['loadAd'],
152
+ });
153
+
154
+ /**
155
+ * Native view component for displaying a banner or MREC ad.
156
+ */
157
+ export default codegenNativeComponent<NativeProps>('AppLovinMAXAdView') as HostComponent<NativeProps>;
@@ -0,0 +1,153 @@
1
+ import type { HostComponent, ViewProps } from 'react-native';
2
+ import type { Double, DirectEventHandler } from 'react-native/Libraries/Types/CodegenTypes';
3
+ import codegenNativeCommands from 'react-native/Libraries/Utilities/codegenNativeCommands';
4
+ import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
5
+
6
+ /**
7
+ * Payload for native ad lifecycle events (e.g., load, click, revenue).
8
+ */
9
+ export type AdInfoEvent = Readonly<{
10
+ adUnitId: string;
11
+ adFormat: string;
12
+ networkName: string;
13
+ networkPlacement: string;
14
+ creativeId?: string | null;
15
+ placement?: string | null;
16
+ revenue: Double;
17
+ revenuePrecision: string;
18
+ latencyMillis: Double;
19
+ dspName?: string | null;
20
+ size: Readonly<{
21
+ width: Double;
22
+ height: Double;
23
+ }>;
24
+
25
+ /**
26
+ * Optional native ad content for display in asset views.
27
+ */
28
+ nativeAd?: Readonly<{
29
+ title?: string;
30
+ advertiser?: string;
31
+ body?: string;
32
+ callToAction?: string;
33
+ starRating?: Double;
34
+ mediaContentAspectRatio?: Double;
35
+ isIconImageAvailable: boolean;
36
+ isOptionsViewAvailable: boolean;
37
+ isMediaViewAvailable: boolean;
38
+ }>;
39
+
40
+ /**
41
+ * Full internal native ad payload used for runtime rendering and view mapping.
42
+ */
43
+ nativeAdImpl: Readonly<{
44
+ title?: string | null;
45
+ advertiser?: string | null;
46
+ body?: string | null;
47
+ callToAction?: string | null;
48
+ image?: boolean;
49
+ imageSource?: string | null;
50
+ url?: string;
51
+ starRating?: Double;
52
+ isOptionsViewAvailable: boolean;
53
+ isMediaViewAvailable: boolean;
54
+ }>;
55
+ }>;
56
+
57
+ /**
58
+ * Payload for native ad load failure events.
59
+ */
60
+ export type AdLoadFailedEvent = Readonly<{
61
+ adUnitId: string;
62
+ code: Double;
63
+ message?: string | null;
64
+ mediatedNetworkErrorCode: Double;
65
+ mediatedNetworkErrorMessage: string;
66
+ adLoadFailureInfo?: string | null;
67
+ }>;
68
+
69
+ /**
70
+ * Props passed to the {@link AppLovinMAXNativeAdView} native component.
71
+ */
72
+ export interface NativeProps extends ViewProps {
73
+ /** Ad unit ID used to load the ad. */
74
+ adUnitId: string;
75
+
76
+ /** Optional placement name for ad tracking. */
77
+ placement?: string | null;
78
+
79
+ /** Optional custom data associated with the ad. */
80
+ customData?: string | null;
81
+
82
+ /** Extra key-value string parameters passed to the SDK. */
83
+ extraParameters?: ReadonlyArray<{
84
+ key: string;
85
+ value: string | null;
86
+ }>;
87
+
88
+ /** Local string parameters passed to the mediation adapter. */
89
+ strLocalExtraParameters?: ReadonlyArray<{
90
+ key: string;
91
+ value: string | null;
92
+ }>;
93
+
94
+ /** Local boolean parameters passed to the mediation adapter. */
95
+ boolLocalExtraParameters?: ReadonlyArray<{
96
+ key: string;
97
+ value: boolean | null;
98
+ }>;
99
+
100
+ /** Called when a native ad is successfully loaded. */
101
+ onAdLoadedEvent: DirectEventHandler<AdInfoEvent>;
102
+
103
+ /** Called when ad loading fails. */
104
+ onAdLoadFailedEvent: DirectEventHandler<AdLoadFailedEvent>;
105
+
106
+ /** Called when the ad is clicked. */
107
+ onAdClickedEvent: DirectEventHandler<AdInfoEvent>;
108
+
109
+ /** Called when ad revenue is reported. */
110
+ onAdRevenuePaidEvent: DirectEventHandler<AdInfoEvent>;
111
+ }
112
+
113
+ type AppLovinMAXNativeAdViewNativeComponentType = HostComponent<NativeProps>;
114
+
115
+ /**
116
+ * Native commands callable from JS for managing {@link NativeAdView}.
117
+ */
118
+ interface NativeCommands {
119
+ /**
120
+ * Manually loads a new native ad.
121
+ *
122
+ * @param viewRef - Reference to the native ad view.
123
+ */
124
+ loadAd(viewRef: React.ElementRef<AppLovinMAXNativeAdViewNativeComponentType>): void;
125
+
126
+ /**
127
+ * Binds a React Native child view to a native asset (e.g. TitleView, IconView).
128
+ *
129
+ * @param viewRef - Reference to the native ad view.
130
+ * @param assetViewTag - React tag for the asset view (via `findNodeHandle()`).
131
+ * @param assetViewName - Name of the asset (e.g., "MediaView", "CallToActionView").
132
+ */
133
+ updateAssetView(viewRef: React.ElementRef<AppLovinMAXNativeAdViewNativeComponentType>, assetViewTag: Double, assetViewName: string): void;
134
+
135
+ /**
136
+ * Instructs the native view to render the bound native ad after all asset views are set.
137
+ *
138
+ * @param viewRef - Reference to the native ad view.
139
+ */
140
+ renderNativeAd(viewRef: React.ElementRef<AppLovinMAXNativeAdViewNativeComponentType>): void;
141
+ }
142
+
143
+ /**
144
+ * JS interface to native ad view commands for {@link AppLovinMAXNativeAdView}.
145
+ */
146
+ export const Commands: NativeCommands = codegenNativeCommands<NativeCommands>({
147
+ supportedCommands: ['loadAd', 'updateAssetView', 'renderNativeAd'],
148
+ });
149
+
150
+ /**
151
+ * Native component for rendering a custom native ad layout using bound asset views.
152
+ */
153
+ export default codegenNativeComponent<NativeProps>('AppLovinMAXNativeAdView') as HostComponent<NativeProps>;