@thealteroffice/react-native-adgeist 0.0.19 → 0.0.22

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 (142) hide show
  1. package/Adgeist.podspec +1 -1
  2. package/README.md +70 -521
  3. package/android/build.gradle +6 -3
  4. package/android/generated/java/com/adgeist/NativeAdgeistSpec.java +11 -11
  5. package/android/generated/java/com/facebook/react/viewmanagers/HTML5AdNativeComponentManagerDelegate.java +55 -0
  6. package/android/generated/java/com/facebook/react/viewmanagers/HTML5AdNativeComponentManagerInterface.java +24 -0
  7. package/android/generated/jni/RNAdgeistSpec-generated.cpp +12 -12
  8. package/android/generated/jni/react/renderer/components/RNAdgeistSpec/ComponentDescriptors.cpp +22 -0
  9. package/android/generated/jni/react/renderer/components/RNAdgeistSpec/ComponentDescriptors.h +24 -0
  10. package/android/generated/jni/react/renderer/components/RNAdgeistSpec/EventEmitters.cpp +60 -0
  11. package/android/generated/jni/react/renderer/components/RNAdgeistSpec/EventEmitters.h +49 -0
  12. package/android/generated/jni/react/renderer/components/RNAdgeistSpec/Props.cpp +28 -0
  13. package/android/generated/jni/react/renderer/components/RNAdgeistSpec/Props.h +52 -0
  14. package/android/generated/jni/react/renderer/components/RNAdgeistSpec/RNAdgeistSpecJSI-generated.cpp +14 -22
  15. package/android/generated/jni/react/renderer/components/RNAdgeistSpec/RNAdgeistSpecJSI.h +36 -36
  16. package/android/generated/jni/react/renderer/components/RNAdgeistSpec/ShadowNodes.cpp +17 -0
  17. package/android/generated/jni/react/renderer/components/RNAdgeistSpec/ShadowNodes.h +32 -0
  18. package/android/generated/jni/react/renderer/components/RNAdgeistSpec/States.cpp +16 -0
  19. package/android/generated/jni/react/renderer/components/RNAdgeistSpec/States.h +29 -0
  20. package/android/src/main/java/com/adgeist/AdgeistPackage.kt +8 -7
  21. package/android/src/main/java/com/adgeist/components/HTML5AdViewManagerImpl.kt +125 -0
  22. package/android/src/main/java/com/adgeist/modules/AdgeistImpl.kt +114 -0
  23. package/android/src/main/java/com/adgeist/utils/CreativeExtensions.kt +151 -0
  24. package/android/src/newarch/java/com/Adgeist.kt +119 -0
  25. package/android/src/newarch/java/com/HTML5AdViewManager.kt +77 -0
  26. package/android/src/oldarch/java/com/Adgeist.kt +132 -0
  27. package/android/src/oldarch/java/com/HTML5AdViewManager.kt +63 -0
  28. package/ios/Adgeist-Bridging-Header.h +3 -0
  29. package/ios/Adgeist.h +1 -1
  30. package/ios/Adgeist.mm +154 -38
  31. package/ios/AdgeistImpl.swift +188 -53
  32. package/ios/NativeHTML5AdManager.h +9 -0
  33. package/ios/NativeHTML5AdManager.mm +178 -0
  34. package/ios/NativeHTML5AdView.swift +136 -0
  35. package/ios/generated/RNAdgeistSpec/ComponentDescriptors.cpp +22 -0
  36. package/ios/generated/RNAdgeistSpec/ComponentDescriptors.h +24 -0
  37. package/ios/generated/RNAdgeistSpec/EventEmitters.cpp +60 -0
  38. package/ios/generated/RNAdgeistSpec/EventEmitters.h +49 -0
  39. package/ios/generated/RNAdgeistSpec/Props.cpp +28 -0
  40. package/ios/generated/RNAdgeistSpec/Props.h +52 -0
  41. package/ios/generated/RNAdgeistSpec/RCTComponentViewHelpers.h +65 -0
  42. package/ios/generated/RNAdgeistSpec/RNAdgeistSpec-generated.mm +17 -17
  43. package/ios/generated/RNAdgeistSpec/RNAdgeistSpec.h +17 -25
  44. package/ios/generated/RNAdgeistSpec/ShadowNodes.cpp +17 -0
  45. package/ios/generated/RNAdgeistSpec/ShadowNodes.h +32 -0
  46. package/ios/generated/RNAdgeistSpec/States.cpp +16 -0
  47. package/ios/generated/RNAdgeistSpec/States.h +29 -0
  48. package/ios/generated/RNAdgeistSpecJSI-generated.cpp +14 -22
  49. package/ios/generated/RNAdgeistSpecJSI.h +36 -36
  50. package/lib/module/cdpclient/index.js +1 -25
  51. package/lib/module/cdpclient/index.js.map +1 -1
  52. package/lib/module/components/HTML5AdView.js +128 -0
  53. package/lib/module/components/HTML5AdView.js.map +1 -0
  54. package/lib/module/components/{BannerAd.js → deprecated/BannerAdView.js} +50 -79
  55. package/lib/module/components/deprecated/BannerAdView.js.map +1 -0
  56. package/lib/module/components/{ConsentModal.js → deprecated/ConsentModal.js} +2 -2
  57. package/lib/module/components/deprecated/ConsentModal.js.map +1 -0
  58. package/lib/module/constants.js +14 -0
  59. package/lib/module/constants.js.map +1 -0
  60. package/lib/module/index.js +3 -2
  61. package/lib/module/index.js.map +1 -1
  62. package/lib/module/{components → providers}/AdgeistProvider.js +10 -35
  63. package/lib/module/providers/AdgeistProvider.js.map +1 -0
  64. package/lib/module/specs/HTML5AdNativeComponent.ts +46 -0
  65. package/lib/module/specs/NativeAdgeist.js.map +1 -0
  66. package/lib/module/types/AdSize.js +2 -0
  67. package/lib/module/types/AdSize.js.map +1 -0
  68. package/lib/module/types/CPMAdResponse.js +2 -0
  69. package/lib/module/types/CPMAdResponse.js.map +1 -0
  70. package/lib/module/types/FixedAdResponse.js +2 -0
  71. package/lib/module/types/FixedAdResponse.js.map +1 -0
  72. package/lib/module/types/HTML5AdNativeComponentProps.js +4 -0
  73. package/lib/module/types/HTML5AdNativeComponentProps.js.map +1 -0
  74. package/lib/module/types/Provider.js +2 -0
  75. package/lib/module/types/Provider.js.map +1 -0
  76. package/lib/typescript/src/cdpclient/index.d.ts +1 -21
  77. package/lib/typescript/src/cdpclient/index.d.ts.map +1 -1
  78. package/lib/typescript/src/components/HTML5AdView.d.ts +3 -0
  79. package/lib/typescript/src/components/HTML5AdView.d.ts.map +1 -0
  80. package/lib/typescript/src/components/deprecated/BannerAdView.d.ts +17 -0
  81. package/lib/typescript/src/components/deprecated/BannerAdView.d.ts.map +1 -0
  82. package/lib/typescript/src/components/deprecated/ConsentModal.d.ts.map +1 -0
  83. package/lib/typescript/src/constants.d.ts +10 -0
  84. package/lib/typescript/src/constants.d.ts.map +1 -0
  85. package/lib/typescript/src/index.d.ts +3 -2
  86. package/lib/typescript/src/index.d.ts.map +1 -1
  87. package/lib/typescript/src/providers/AdgeistProvider.d.ts +9 -0
  88. package/lib/typescript/src/providers/AdgeistProvider.d.ts.map +1 -0
  89. package/lib/typescript/src/specs/HTML5AdNativeComponent.d.ts +29 -0
  90. package/lib/typescript/src/specs/HTML5AdNativeComponent.d.ts.map +1 -0
  91. package/lib/typescript/src/specs/NativeAdgeist.d.ts +28 -0
  92. package/lib/typescript/src/specs/NativeAdgeist.d.ts.map +1 -0
  93. package/lib/typescript/src/types/AdSize.d.ts +5 -0
  94. package/lib/typescript/src/types/AdSize.d.ts.map +1 -0
  95. package/lib/typescript/src/types/CPMAdResponse.d.ts +25 -0
  96. package/lib/typescript/src/types/CPMAdResponse.d.ts.map +1 -0
  97. package/lib/typescript/src/types/FixedAdResponse.d.ts +50 -0
  98. package/lib/typescript/src/types/FixedAdResponse.d.ts.map +1 -0
  99. package/lib/typescript/src/types/HTML5AdNativeComponentProps.d.ts +24 -0
  100. package/lib/typescript/src/types/HTML5AdNativeComponentProps.d.ts.map +1 -0
  101. package/lib/typescript/src/types/Provider.d.ts +16 -0
  102. package/lib/typescript/src/types/Provider.d.ts.map +1 -0
  103. package/package.json +8 -3
  104. package/plugin/build/android/withRNAdgeistMainApplication.d.ts +3 -0
  105. package/plugin/build/android/withRNAdgeistMainApplication.js +65 -0
  106. package/plugin/build/index.d.ts +3 -0
  107. package/plugin/build/index.js +25 -0
  108. package/plugin/build/ios/withRNAdgeistAppDelegate.d.ts +4 -0
  109. package/plugin/build/ios/withRNAdgeistAppDelegate.js +66 -0
  110. package/react-native.config.js +1 -1
  111. package/src/cdpclient/index.ts +1 -21
  112. package/src/components/HTML5AdView.tsx +161 -0
  113. package/src/components/{BannerAd.tsx → deprecated/BannerAdView.tsx} +80 -115
  114. package/src/components/{ConsentModal.tsx → deprecated/ConsentModal.tsx} +2 -2
  115. package/src/constants.ts +8 -0
  116. package/src/index.tsx +4 -2
  117. package/src/{components → providers}/AdgeistProvider.tsx +26 -60
  118. package/src/specs/HTML5AdNativeComponent.ts +46 -0
  119. package/src/{NativeAdgeist.ts → specs/NativeAdgeist.ts} +26 -25
  120. package/src/types/AdSize.ts +4 -0
  121. package/src/types/CPMAdResponse.ts +26 -0
  122. package/src/types/FixedAdResponse.ts +51 -0
  123. package/src/types/HTML5AdNativeComponentProps.ts +28 -0
  124. package/src/types/Provider.ts +16 -0
  125. package/android/src/main/AndroidManifestNew.xml +0 -2
  126. package/android/src/main/java/com/adgeist/implementation/AdgeistModuleImpl.kt +0 -252
  127. package/android/src/newarch/java/com/AdgeistModule.kt +0 -135
  128. package/android/src/oldarch/java/com/AdgeistModule.kt +0 -148
  129. package/ios/adgeist-Bridging-Header.h +0 -1
  130. package/lib/module/NativeAdgeist.js.map +0 -1
  131. package/lib/module/components/AdgeistProvider.js.map +0 -1
  132. package/lib/module/components/BannerAd.js.map +0 -1
  133. package/lib/module/components/ConsentModal.js.map +0 -1
  134. package/lib/typescript/src/NativeAdgeist.d.ts +0 -28
  135. package/lib/typescript/src/NativeAdgeist.d.ts.map +0 -1
  136. package/lib/typescript/src/components/AdgeistProvider.d.ts +0 -50
  137. package/lib/typescript/src/components/AdgeistProvider.d.ts.map +0 -1
  138. package/lib/typescript/src/components/BannerAd.d.ts +0 -64
  139. package/lib/typescript/src/components/BannerAd.d.ts.map +0 -1
  140. package/lib/typescript/src/components/ConsentModal.d.ts.map +0 -1
  141. /package/lib/module/{NativeAdgeist.js → specs/NativeAdgeist.js} +0 -0
  142. /package/lib/typescript/src/components/{ConsentModal.d.ts → deprecated/ConsentModal.d.ts} +0 -0
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.withRNAdgeistMainApplication = void 0;
4
+ exports.ktFileUpdater = ktFileUpdater;
5
+ const config_plugins_1 = require("@expo/config-plugins");
6
+ const generateCode_1 = require("@expo/config-plugins/build/utils/generateCode");
7
+ const withRNAdgeistMainApplication = (config) => {
8
+ return (0, config_plugins_1.withAppBuildGradle)((0, config_plugins_1.withMainApplication)(config, readMainApplicationFileAndUpdateContents), readBuildGradleFileAndUpdateContents);
9
+ };
10
+ exports.withRNAdgeistMainApplication = withRNAdgeistMainApplication;
11
+ // 1. MainActivity Modifications
12
+ async function readMainApplicationFileAndUpdateContents(config) {
13
+ const { modResults: mainApplicationFile } = config;
14
+ const worker = getCompatibleFileUpdater(mainApplicationFile.language);
15
+ mainApplicationFile.contents = worker(mainApplicationFile.contents);
16
+ return config;
17
+ }
18
+ function readBuildGradleFileAndUpdateContents(config) {
19
+ const { modResults } = config;
20
+ if (!modResults.contents.includes('implementation "ai.adgeist:adgeistkit:')) {
21
+ modResults.contents = modResults.contents.replace(/dependencies\s*{/, `dependencies {
22
+ implementation "ai.adgeist:adgeistkit:0.0.1" // AdgeistKit Dependency`);
23
+ }
24
+ return config;
25
+ }
26
+ function getCompatibleFileUpdater(language) {
27
+ switch (language) {
28
+ case 'kt':
29
+ return ktFileUpdater;
30
+ default:
31
+ throw new Error(`Cannot add React Native Orientation Director code to MainActivity of language "${language}"`);
32
+ }
33
+ }
34
+ function ktFileUpdater(originalContents) {
35
+ // Safer anchor detection
36
+ const anchors = [
37
+ /super\.onCreate\(/,
38
+ /@Override\s+fun onCreate\(/,
39
+ /class \w+ : ReactActivity/,
40
+ ].find((anchor) => anchor.test(originalContents));
41
+ if (!anchors) {
42
+ throw new Error('Could not find suitable insertion point in MainActivity');
43
+ }
44
+ const packageImportCodeBlock = 'import com.adgeist.AdgeistPackage';
45
+ const rightBeforeClassDeclaration = /import com.facebook.react.ReactPackage/;
46
+ const importMergeResults = (0, generateCode_1.mergeContents)({
47
+ tag: '@react-native-adgeist/package-import',
48
+ src: originalContents,
49
+ newSrc: packageImportCodeBlock,
50
+ anchor: rightBeforeClassDeclaration,
51
+ offset: 0,
52
+ comment: '// React Native Adgeist',
53
+ });
54
+ const onConfigurationChangedCodeBlock = `packages.add(AdgeistPackage())`;
55
+ const rightBeforeOnReturnStatement = /return packages/;
56
+ const implementationMergeResults = (0, generateCode_1.mergeContents)({
57
+ tag: '@react-native-adgeist/package-initialization',
58
+ src: importMergeResults.contents,
59
+ newSrc: onConfigurationChangedCodeBlock,
60
+ anchor: rightBeforeOnReturnStatement,
61
+ offset: 0,
62
+ comment: '// Package Initialization',
63
+ });
64
+ return implementationMergeResults.contents;
65
+ }
@@ -0,0 +1,3 @@
1
+ import { type ConfigPlugin } from '@expo/config-plugins';
2
+ declare const _default: ConfigPlugin<void>;
3
+ export default _default;
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const config_plugins_1 = require("@expo/config-plugins");
4
+ const withRNAdgeistMainApplication_1 = require("./android/withRNAdgeistMainApplication");
5
+ const withRNAdgeistAppDelegate_1 = require("./ios/withRNAdgeistAppDelegate");
6
+ /**
7
+ * So, expo config plugin are awesome and the documentation is well written, but I still needed to look around to see
8
+ * how other projects actually modify the AppDelegate. I've found react-native-firebase to implement a plugin config
9
+ * that changes the AppDelegate, so I'll leave their link as reference:
10
+ * https://github.com/invertase/react-native-firebase/blob/main/packages/app/plugin/src/ios/appDelegate.ts
11
+ *
12
+ * Kudos to them, because this stuff is hard!
13
+ *
14
+ * @param config
15
+ */
16
+ const withRNAdgeist = (config) => {
17
+ return (0, config_plugins_1.withPlugins)(config, [
18
+ //Android
19
+ withRNAdgeistMainApplication_1.withRNAdgeistMainApplication,
20
+ //iOS
21
+ withRNAdgeistAppDelegate_1.withRNAdgeistAppDelegate,
22
+ ]);
23
+ };
24
+ const pak = require('@thealteroffice/react-native-adgeist/package.json');
25
+ exports.default = (0, config_plugins_1.createRunOncePlugin)(withRNAdgeist, pak.name, pak.version);
@@ -0,0 +1,4 @@
1
+ import { type ConfigPlugin } from '@expo/config-plugins';
2
+ export declare const withRNAdgeistAppDelegate: ConfigPlugin;
3
+ export declare function swiftFileUpdater(originalContents: string): string;
4
+ export declare function objCFileUpdater(originalContents: string): string;
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.withRNAdgeistAppDelegate = void 0;
4
+ exports.swiftFileUpdater = swiftFileUpdater;
5
+ exports.objCFileUpdater = objCFileUpdater;
6
+ const config_plugins_1 = require("@expo/config-plugins");
7
+ const generateCode_1 = require("@expo/config-plugins/build/utils/generateCode");
8
+ const withRNAdgeistAppDelegate = (config) => {
9
+ return (0, config_plugins_1.withAppDelegate)(config, readAppDelegateFileAndUpdateContents);
10
+ };
11
+ exports.withRNAdgeistAppDelegate = withRNAdgeistAppDelegate;
12
+ async function readAppDelegateFileAndUpdateContents(config) {
13
+ const { modResults: appDelegateFile } = config;
14
+ const worker = getCompatibleFileUpdater(appDelegateFile.language);
15
+ appDelegateFile.contents = worker(appDelegateFile.contents);
16
+ return config;
17
+ }
18
+ function getCompatibleFileUpdater(language) {
19
+ switch (language) {
20
+ case 'objc':
21
+ case 'objcpp': {
22
+ return objCFileUpdater;
23
+ }
24
+ case 'swift':
25
+ return swiftFileUpdater;
26
+ default:
27
+ throw new Error(`Cannot add React Native Adgeist code to AppDelegate of language "${language}"`);
28
+ }
29
+ }
30
+ function swiftFileUpdater(originalContents) {
31
+ const wantsToAddAnyCodeBlock = ``;
32
+ const rightBeforeLastClosingBrace = /didFinishLaunchingWithOptions:\s*launchOptions\)/g;
33
+ const pasteInTheListJustAfterTheClosingBracket = 2;
34
+ const results = (0, generateCode_1.mergeContents)({
35
+ tag: '@react-native-adgeist/implementation',
36
+ src: originalContents,
37
+ newSrc: wantsToAddAnyCodeBlock,
38
+ anchor: rightBeforeLastClosingBrace,
39
+ offset: pasteInTheListJustAfterTheClosingBracket,
40
+ comment: '// React Native Ageist',
41
+ });
42
+ return results.contents;
43
+ }
44
+ function objCFileUpdater(originalContents) {
45
+ const libraryHeaderImportCodeBlock = '#import "Adgeist.h"\n';
46
+ const rightBeforeAppDelegateImplementation = /@implementation\s+\w+/g;
47
+ const headerImportMergeResults = (0, generateCode_1.mergeContents)({
48
+ tag: '@react-native-adgeist/library-header-import',
49
+ src: originalContents,
50
+ newSrc: libraryHeaderImportCodeBlock,
51
+ anchor: rightBeforeAppDelegateImplementation,
52
+ offset: 0,
53
+ comment: '// React Native Ageist',
54
+ });
55
+ const wantsToAddAnyCodeBlock = ``;
56
+ const rightBeforeLastClosingEnd = /@end[^@]*$/g;
57
+ const implementationMergeResults = (0, generateCode_1.mergeContents)({
58
+ tag: '@react-native-adgeist/implementation',
59
+ src: headerImportMergeResults.contents,
60
+ newSrc: wantsToAddAnyCodeBlock,
61
+ anchor: rightBeforeLastClosingEnd,
62
+ offset: 0,
63
+ comment: '// React Native Ageist',
64
+ });
65
+ return implementationMergeResults.contents;
66
+ }
@@ -5,7 +5,7 @@ module.exports = {
5
5
  dependency: {
6
6
  platforms: {
7
7
  android: {
8
- cmakeListsPath: 'build/generated/source/codegen/jni/CMakeLists.txt',
8
+ cmakeListsPath: 'generated/jni/CMakeLists.txt',
9
9
  },
10
10
  },
11
11
  },
@@ -1,4 +1,4 @@
1
- import Adgeist, { type UserDetails, type Event } from '../NativeAdgeist';
1
+ import Adgeist, { type UserDetails, type Event } from '../specs/NativeAdgeist';
2
2
 
3
3
  class AdgeistError extends Error {
4
4
  code?: string;
@@ -11,11 +11,6 @@ class AdgeistError extends Error {
11
11
  }
12
12
  }
13
13
 
14
- /**
15
- * Sets user details in the Adgeist SDK
16
- * @param userDetails - User details object
17
- * @throws AdgeistError if the operation fails
18
- */
19
14
  export const setUserDetails = (userDetails: UserDetails): void => {
20
15
  try {
21
16
  Adgeist.setUserDetails(userDetails);
@@ -26,11 +21,6 @@ export const setUserDetails = (userDetails: UserDetails): void => {
26
21
  }
27
22
  };
28
23
 
29
- /**
30
- * Logs an event in the Adgeist SDK
31
- * @param event - Event object to log
32
- * @throws AdgeistError if the event is invalid or logging fails
33
- */
34
24
  export const logEvent = (event: Event): void => {
35
25
  if (!event || typeof event !== 'object') {
36
26
  throw new AdgeistError('Event must be a valid object');
@@ -44,11 +34,6 @@ export const logEvent = (event: Event): void => {
44
34
  }
45
35
  };
46
36
 
47
- /**
48
- * Retrieves the consent status from the Adgeist SDK
49
- * @returns Promise resolving to 'ACCEPTED' or 'DENIED'
50
- * @throws AdgeistError if the operation fails
51
- */
52
37
  export const getConsentStatus = async (): Promise<'ACCEPTED' | 'DENIED'> => {
53
38
  try {
54
39
  const status = await Adgeist.getConsentStatus();
@@ -62,11 +47,6 @@ export const getConsentStatus = async (): Promise<'ACCEPTED' | 'DENIED'> => {
62
47
  }
63
48
  };
64
49
 
65
- /**
66
- * Updates the consent status in the Adgeist SDK
67
- * @param consent - Boolean indicating user consent
68
- * @throws AdgeistError if the operation fails
69
- */
70
50
  export const updateConsentStatus = (consent: boolean): void => {
71
51
  try {
72
52
  Adgeist.updateConsentStatus(consent);
@@ -0,0 +1,161 @@
1
+ import {
2
+ useRef,
3
+ useCallback,
4
+ useImperativeHandle,
5
+ forwardRef,
6
+ useEffect,
7
+ useState,
8
+ useMemo,
9
+ } from 'react';
10
+ import type { ViewStyle, DimensionValue } from 'react-native';
11
+
12
+ import { useAdgeistContext } from '../providers/AdgeistProvider';
13
+ import HTML5AdNativeComponent, {
14
+ Commands,
15
+ } from '../specs/HTML5AdNativeComponent';
16
+ import type {
17
+ HTML5AdNativeComponentProps,
18
+ HTML5AdRequest,
19
+ HTML5AdViewRef,
20
+ } from '../types/HTML5AdNativeComponentProps';
21
+ import { AdSizes } from '../constants';
22
+
23
+ export const HTML5AdView = forwardRef<
24
+ HTML5AdViewRef,
25
+ HTML5AdNativeComponentProps & HTML5AdRequest
26
+ >(
27
+ (
28
+ {
29
+ adUnitID,
30
+ adIsResponsive,
31
+ adSize,
32
+ adType,
33
+ onAdLoaded,
34
+ onAdFailedToLoad,
35
+ onAdOpened,
36
+ onAdClosed,
37
+ onAdClicked,
38
+ },
39
+ ref
40
+ ) => {
41
+ const { isTestEnvironment } = useAdgeistContext();
42
+
43
+ const nativeRef = useRef<any>(null);
44
+ const [isViewReady, setIsViewReady] = useState(false);
45
+ const pendingLoadRef = useRef<HTML5AdRequest | null>(null);
46
+
47
+ const dimensions = useMemo<{
48
+ width: DimensionValue;
49
+ height: DimensionValue;
50
+ }>(() => {
51
+ const width: DimensionValue = adSize?.width ?? '100%';
52
+ const height: DimensionValue = adSize?.height ?? '100%';
53
+ return { width, height };
54
+ }, [adSize?.width, adSize?.height]);
55
+
56
+ const containerStyle = useMemo<ViewStyle>(
57
+ () => ({
58
+ width: dimensions.width,
59
+ height: dimensions.height,
60
+ }),
61
+ [dimensions]
62
+ );
63
+
64
+ const loadAdInternal = useCallback(
65
+ (request: HTML5AdRequest = { isTestMode: isTestEnvironment }) => {
66
+ if (!nativeRef.current) {
67
+ console.warn('HTML5AdView: Cannot load ad, native view not ready');
68
+ return;
69
+ }
70
+
71
+ const finalRequest = {
72
+ ...request,
73
+ isTestMode: request.isTestMode ?? isTestEnvironment,
74
+ };
75
+
76
+ try {
77
+ Commands.loadAd(nativeRef.current, finalRequest.isTestMode);
78
+ } catch (error) {
79
+ if (__DEV__) {
80
+ console.warn('HTML5AdView: Error loading ad:', error);
81
+ }
82
+ }
83
+ },
84
+ [isTestEnvironment]
85
+ );
86
+
87
+ const handleNativeRef = useCallback((ref: any) => {
88
+ nativeRef.current = ref;
89
+
90
+ if (ref) {
91
+ // Mark as ready in the next animation frame (ensures layout pass completed)
92
+ requestAnimationFrame(() => {
93
+ setIsViewReady(true);
94
+ });
95
+ } else {
96
+ setIsViewReady(false);
97
+ }
98
+ }, []);
99
+
100
+ useEffect(() => {
101
+ if (isViewReady && adUnitID) {
102
+ const request: HTML5AdRequest = { isTestMode: isTestEnvironment };
103
+ if (pendingLoadRef.current) {
104
+ loadAdInternal(pendingLoadRef.current);
105
+ pendingLoadRef.current = null;
106
+ } else {
107
+ loadAdInternal(request);
108
+ }
109
+ }
110
+ }, [isViewReady, adUnitID, isTestEnvironment, loadAdInternal]);
111
+
112
+ useImperativeHandle(
113
+ ref,
114
+ () => ({
115
+ loadAd: (adRequest?: HTML5AdRequest) => {
116
+ const request = adRequest || { isTestMode: isTestEnvironment };
117
+
118
+ if (isViewReady && nativeRef.current) {
119
+ loadAdInternal(request);
120
+ } else {
121
+ pendingLoadRef.current = request;
122
+ }
123
+ },
124
+ destroy: () => {
125
+ if (nativeRef.current) {
126
+ try {
127
+ Commands.destroy(nativeRef.current);
128
+ } catch (e) {
129
+ console.warn('Error destroying ad view:', e);
130
+ }
131
+ }
132
+ },
133
+ }),
134
+ [isViewReady, isTestEnvironment, loadAdInternal]
135
+ );
136
+
137
+ if (__DEV__) {
138
+ console.log('[HTML5AdView]', { adUnitID, adSize, adType, isViewReady });
139
+ }
140
+
141
+ return (
142
+ <HTML5AdNativeComponent
143
+ ref={handleNativeRef}
144
+ style={containerStyle}
145
+ // Required Props, it will take values from React Component props
146
+ adUnitID={adUnitID}
147
+ adSize={adIsResponsive ? AdSizes.Responsive : adSize}
148
+ adIsResponsive={adIsResponsive}
149
+ adType={adType}
150
+ // Required Event Callbacks
151
+ onAdLoaded={onAdLoaded}
152
+ onAdFailedToLoad={onAdFailedToLoad}
153
+ onAdOpened={onAdOpened}
154
+ onAdClosed={onAdClosed}
155
+ onAdClicked={onAdClicked}
156
+ />
157
+ );
158
+ }
159
+ );
160
+
161
+ HTML5AdView.displayName = 'HTML5AdView';