@vynix-org/react-native-ads-sdk 0.1.1

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 (128) hide show
  1. package/AdsSdk.podspec +52 -0
  2. package/LICENSE +20 -0
  3. package/README.md +95 -0
  4. package/android/build.gradle +108 -0
  5. package/android/gradle.properties +5 -0
  6. package/android/src/main/AndroidManifest.xml +5 -0
  7. package/android/src/main/java/com/adssdk/AdsSdkModule.kt +23 -0
  8. package/android/src/main/java/com/adssdk/AdsSdkPackage.kt +33 -0
  9. package/ios/AdsSdk.h +5 -0
  10. package/ios/AdsSdk.mm +18 -0
  11. package/lib/module/ads-manager/AppOpenAdsManager.js +131 -0
  12. package/lib/module/ads-manager/AppOpenAdsManager.js.map +1 -0
  13. package/lib/module/ads-manager/GoogleMobileAdsManager.js +62 -0
  14. package/lib/module/ads-manager/GoogleMobileAdsManager.js.map +1 -0
  15. package/lib/module/ads-manager/InterstitialAdsManager.js +291 -0
  16. package/lib/module/ads-manager/InterstitialAdsManager.js.map +1 -0
  17. package/lib/module/ads-manager/NativeAdsManager.js +405 -0
  18. package/lib/module/ads-manager/NativeAdsManager.js.map +1 -0
  19. package/lib/module/ads-manager/RewardedAdsManager.js +328 -0
  20. package/lib/module/ads-manager/RewardedAdsManager.js.map +1 -0
  21. package/lib/module/ads-manager/RewardedInterstitialAdsManager.js +328 -0
  22. package/lib/module/ads-manager/RewardedInterstitialAdsManager.js.map +1 -0
  23. package/lib/module/components/BannerAdComponent.js +159 -0
  24. package/lib/module/components/BannerAdComponent.js.map +1 -0
  25. package/lib/module/components/FullscreenStyles.js +162 -0
  26. package/lib/module/components/FullscreenStyles.js.map +1 -0
  27. package/lib/module/components/NativeAdComponent.js +172 -0
  28. package/lib/module/components/NativeAdComponent.js.map +1 -0
  29. package/lib/module/components/NativeAdFullscreenComponent.js +205 -0
  30. package/lib/module/components/NativeAdFullscreenComponent.js.map +1 -0
  31. package/lib/module/components/NativeStyles.js +143 -0
  32. package/lib/module/components/NativeStyles.js.map +1 -0
  33. package/lib/module/event/custom-event.js +29 -0
  34. package/lib/module/event/custom-event.js.map +1 -0
  35. package/lib/module/hook/useAppOpenAd.js +138 -0
  36. package/lib/module/hook/useAppOpenAd.js.map +1 -0
  37. package/lib/module/hook/useInterstitialAd.js +157 -0
  38. package/lib/module/hook/useInterstitialAd.js.map +1 -0
  39. package/lib/module/hook/useNativeAd.js +147 -0
  40. package/lib/module/hook/useNativeAd.js.map +1 -0
  41. package/lib/module/hook/useRewardedAd.js +166 -0
  42. package/lib/module/hook/useRewardedAd.js.map +1 -0
  43. package/lib/module/hook/useRewardedInterstitialAd.js +166 -0
  44. package/lib/module/hook/useRewardedInterstitialAd.js.map +1 -0
  45. package/lib/module/index.js +14 -0
  46. package/lib/module/index.js.map +1 -0
  47. package/lib/module/package.json +1 -0
  48. package/lib/module/stores/interstitial-ads-store.js +205 -0
  49. package/lib/module/stores/interstitial-ads-store.js.map +1 -0
  50. package/lib/module/stores/native-ads-store.js +204 -0
  51. package/lib/module/stores/native-ads-store.js.map +1 -0
  52. package/lib/module/stores/rewarded-ads-store.js +216 -0
  53. package/lib/module/stores/rewarded-ads-store.js.map +1 -0
  54. package/lib/module/stores/rewarded-interstitial-ads-store.js +216 -0
  55. package/lib/module/stores/rewarded-interstitial-ads-store.js.map +1 -0
  56. package/lib/module/types/ads-types.js +25 -0
  57. package/lib/module/types/ads-types.js.map +1 -0
  58. package/lib/typescript/package.json +1 -0
  59. package/lib/typescript/src/ads-manager/AppOpenAdsManager.d.ts +38 -0
  60. package/lib/typescript/src/ads-manager/AppOpenAdsManager.d.ts.map +1 -0
  61. package/lib/typescript/src/ads-manager/GoogleMobileAdsManager.d.ts +22 -0
  62. package/lib/typescript/src/ads-manager/GoogleMobileAdsManager.d.ts.map +1 -0
  63. package/lib/typescript/src/ads-manager/InterstitialAdsManager.d.ts +22 -0
  64. package/lib/typescript/src/ads-manager/InterstitialAdsManager.d.ts.map +1 -0
  65. package/lib/typescript/src/ads-manager/NativeAdsManager.d.ts +59 -0
  66. package/lib/typescript/src/ads-manager/NativeAdsManager.d.ts.map +1 -0
  67. package/lib/typescript/src/ads-manager/RewardedAdsManager.d.ts +25 -0
  68. package/lib/typescript/src/ads-manager/RewardedAdsManager.d.ts.map +1 -0
  69. package/lib/typescript/src/ads-manager/RewardedInterstitialAdsManager.d.ts +25 -0
  70. package/lib/typescript/src/ads-manager/RewardedInterstitialAdsManager.d.ts.map +1 -0
  71. package/lib/typescript/src/components/BannerAdComponent.d.ts +22 -0
  72. package/lib/typescript/src/components/BannerAdComponent.d.ts.map +1 -0
  73. package/lib/typescript/src/components/FullscreenStyles.d.ts +155 -0
  74. package/lib/typescript/src/components/FullscreenStyles.d.ts.map +1 -0
  75. package/lib/typescript/src/components/NativeAdComponent.d.ts +24 -0
  76. package/lib/typescript/src/components/NativeAdComponent.d.ts.map +1 -0
  77. package/lib/typescript/src/components/NativeAdFullscreenComponent.d.ts +26 -0
  78. package/lib/typescript/src/components/NativeAdFullscreenComponent.d.ts.map +1 -0
  79. package/lib/typescript/src/components/NativeStyles.d.ts +139 -0
  80. package/lib/typescript/src/components/NativeStyles.d.ts.map +1 -0
  81. package/lib/typescript/src/event/custom-event.d.ts +8 -0
  82. package/lib/typescript/src/event/custom-event.d.ts.map +1 -0
  83. package/lib/typescript/src/hook/useAppOpenAd.d.ts +19 -0
  84. package/lib/typescript/src/hook/useAppOpenAd.d.ts.map +1 -0
  85. package/lib/typescript/src/hook/useInterstitialAd.d.ts +20 -0
  86. package/lib/typescript/src/hook/useInterstitialAd.d.ts.map +1 -0
  87. package/lib/typescript/src/hook/useNativeAd.d.ts +20 -0
  88. package/lib/typescript/src/hook/useNativeAd.d.ts.map +1 -0
  89. package/lib/typescript/src/hook/useRewardedAd.d.ts +27 -0
  90. package/lib/typescript/src/hook/useRewardedAd.d.ts.map +1 -0
  91. package/lib/typescript/src/hook/useRewardedInterstitialAd.d.ts +27 -0
  92. package/lib/typescript/src/hook/useRewardedInterstitialAd.d.ts.map +1 -0
  93. package/lib/typescript/src/index.d.ts +10 -0
  94. package/lib/typescript/src/index.d.ts.map +1 -0
  95. package/lib/typescript/src/stores/interstitial-ads-store.d.ts +36 -0
  96. package/lib/typescript/src/stores/interstitial-ads-store.d.ts.map +1 -0
  97. package/lib/typescript/src/stores/native-ads-store.d.ts +36 -0
  98. package/lib/typescript/src/stores/native-ads-store.d.ts.map +1 -0
  99. package/lib/typescript/src/stores/rewarded-ads-store.d.ts +39 -0
  100. package/lib/typescript/src/stores/rewarded-ads-store.d.ts.map +1 -0
  101. package/lib/typescript/src/stores/rewarded-interstitial-ads-store.d.ts +39 -0
  102. package/lib/typescript/src/stores/rewarded-interstitial-ads-store.d.ts.map +1 -0
  103. package/lib/typescript/src/types/ads-types.d.ts +164 -0
  104. package/lib/typescript/src/types/ads-types.d.ts.map +1 -0
  105. package/package.json +177 -0
  106. package/src/ads-manager/AppOpenAdsManager.ts +155 -0
  107. package/src/ads-manager/GoogleMobileAdsManager.ts +68 -0
  108. package/src/ads-manager/InterstitialAdsManager.ts +371 -0
  109. package/src/ads-manager/NativeAdsManager.ts +445 -0
  110. package/src/ads-manager/RewardedAdsManager.ts +383 -0
  111. package/src/ads-manager/RewardedInterstitialAdsManager.ts +410 -0
  112. package/src/components/BannerAdComponent.tsx +205 -0
  113. package/src/components/FullscreenStyles.ts +158 -0
  114. package/src/components/NativeAdComponent.tsx +208 -0
  115. package/src/components/NativeAdFullscreenComponent.tsx +261 -0
  116. package/src/components/NativeStyles.ts +141 -0
  117. package/src/event/custom-event.ts +30 -0
  118. package/src/hook/useAppOpenAd.ts +161 -0
  119. package/src/hook/useInterstitialAd.ts +195 -0
  120. package/src/hook/useNativeAd.ts +173 -0
  121. package/src/hook/useRewardedAd.ts +205 -0
  122. package/src/hook/useRewardedInterstitialAd.ts +212 -0
  123. package/src/index.tsx +33 -0
  124. package/src/stores/interstitial-ads-store.ts +287 -0
  125. package/src/stores/native-ads-store.ts +272 -0
  126. package/src/stores/rewarded-ads-store.ts +290 -0
  127. package/src/stores/rewarded-interstitial-ads-store.ts +318 -0
  128. package/src/types/ads-types.ts +239 -0
@@ -0,0 +1,290 @@
1
+ import { create } from 'zustand';
2
+ import { subscribeWithSelector } from 'zustand/middleware';
3
+ import { rewardedAdsManager } from '../ads-manager/RewardedAdsManager';
4
+ import {
5
+ AdStatus,
6
+ type RewardedAdInstance,
7
+ type RewardedAdConfig,
8
+ } from '../types/ads-types';
9
+
10
+ interface RewardedAdStore {
11
+ // State
12
+ ads: Map<string, RewardedAdInstance>;
13
+ loadingKeys: Set<string>;
14
+ errors: Map<string, string>;
15
+
16
+ // Actions - CẬP NHẬT SIGNATURES
17
+ preloadAd: (config: RewardedAdConfig) => Promise<void>;
18
+ loadAd: (config: RewardedAdConfig) => Promise<void>;
19
+ displayAd: (
20
+ adKey: string
21
+ ) => Promise<{ ad: RewardedAdInstance | null; reward: any }>;
22
+ removeAd: (adKey: string) => void;
23
+ refreshAd: (adKey: string) => Promise<void>;
24
+ clearAllAds: () => void;
25
+
26
+ // Getters
27
+ getAd: (adKey: string) => RewardedAdInstance | null;
28
+ isLoading: (adKey: string) => boolean;
29
+ getError: (adKey: string) => string | null;
30
+ getAllAds: () => RewardedAdInstance[];
31
+ getLoadedAds: () => RewardedAdInstance[];
32
+ getErrorAds: () => RewardedAdInstance[];
33
+ isUsingHighPriority: (adKey: string) => boolean; // THÊM MỚI
34
+ hasTriedHighPriority: (adKey: string) => boolean; // THÊM MỚI
35
+
36
+ // Internal actions
37
+ _updateAd: (ad: RewardedAdInstance) => void;
38
+ _removeAd: (adKey: string) => void;
39
+ _setLoading: (adKey: string, loading: boolean) => void;
40
+ _setError: (adKey: string, error: string | null) => void;
41
+ _clearError: (adKey: string) => void;
42
+ }
43
+
44
+ export const useRewardedAdStore = create<RewardedAdStore>()(
45
+ subscribeWithSelector((set, get) => ({
46
+ // Initial state
47
+ ads: new Map(),
48
+ loadingKeys: new Set(),
49
+ errors: new Map(),
50
+
51
+ // Public actions - CẬP NHẬT IMPLEMENTATIONS
52
+ preloadAd: async (config) => {
53
+ const { adKey } = config;
54
+ try {
55
+ get()._setLoading(adKey, true);
56
+ get()._clearError(adKey);
57
+
58
+ await rewardedAdsManager.preloadAd(config);
59
+
60
+ const ad = rewardedAdsManager.getAd(adKey);
61
+ if (ad) {
62
+ get()._updateAd(ad);
63
+ }
64
+ } catch (error) {
65
+ const errorMessage =
66
+ error instanceof Error ? error.message : String(error);
67
+ get()._setError(adKey, errorMessage);
68
+ console.error(`Failed to preload rewarded ad ${adKey}:`, errorMessage);
69
+ } finally {
70
+ get()._setLoading(adKey, false);
71
+ }
72
+ },
73
+
74
+ loadAd: async (config) => {
75
+ return get().preloadAd(config);
76
+ },
77
+
78
+ displayAd: async (adKey) => {
79
+ try {
80
+ get()._clearError(adKey);
81
+
82
+ const result = await rewardedAdsManager.displayAd(adKey);
83
+ if (result.ad) {
84
+ get()._updateAd(result.ad);
85
+ }
86
+ return result;
87
+ } catch (error) {
88
+ const errorMessage =
89
+ error instanceof Error ? error.message : String(error);
90
+ get()._setError(adKey, errorMessage);
91
+ console.error(`Failed to display rewarded ad ${adKey}:`, errorMessage);
92
+ return { ad: null, reward: null };
93
+ }
94
+ },
95
+
96
+ removeAd: (adKey) => {
97
+ rewardedAdsManager.removeAd(adKey);
98
+ get()._removeAd(adKey);
99
+ },
100
+
101
+ refreshAd: async (adKey) => {
102
+ try {
103
+ get()._setLoading(adKey, true);
104
+ get()._clearError(adKey);
105
+
106
+ await rewardedAdsManager.refreshAd(adKey);
107
+
108
+ const ad = rewardedAdsManager.getAd(adKey);
109
+ if (ad) {
110
+ get()._updateAd(ad);
111
+ }
112
+ } catch (error) {
113
+ const errorMessage =
114
+ error instanceof Error ? error.message : String(error);
115
+ get()._setError(adKey, errorMessage);
116
+ console.error(`Failed to refresh rewarded ad ${adKey}:`, errorMessage);
117
+ } finally {
118
+ get()._setLoading(adKey, false);
119
+ }
120
+ },
121
+
122
+ clearAllAds: () => {
123
+ rewardedAdsManager.clearAllAds();
124
+ set({
125
+ ads: new Map(),
126
+ loadingKeys: new Set(),
127
+ errors: new Map(),
128
+ });
129
+ },
130
+
131
+ // Getters
132
+ getAd: (adKey) => {
133
+ return get().ads.get(adKey) || null;
134
+ },
135
+
136
+ isLoading: (adKey) => {
137
+ return get().loadingKeys.has(adKey);
138
+ },
139
+
140
+ getError: (adKey) => {
141
+ return get().errors.get(adKey) || null;
142
+ },
143
+
144
+ getAllAds: () => {
145
+ return Array.from(get().ads.values());
146
+ },
147
+
148
+ getLoadedAds: () => {
149
+ return Array.from(get().ads.values()).filter(
150
+ (ad) => ad.status === AdStatus.LOADED
151
+ );
152
+ },
153
+
154
+ getErrorAds: () => {
155
+ return Array.from(get().ads.values()).filter(
156
+ (ad) => ad.status === AdStatus.ERROR
157
+ );
158
+ },
159
+
160
+ // THÊM MỚI
161
+ isUsingHighPriority: (adKey) => {
162
+ const ad = get().ads.get(adKey);
163
+ return ad?.isUsingHighPriority ?? false;
164
+ },
165
+
166
+ hasTriedHighPriority: (adKey) => {
167
+ const ad = get().ads.get(adKey);
168
+ return ad?.hasTriedHighPriority ?? false;
169
+ },
170
+
171
+ // Internal actions
172
+ _updateAd: (ad) => {
173
+ set((state) => ({
174
+ ads: new Map(state.ads.set(ad.adKey, ad)),
175
+ }));
176
+ },
177
+
178
+ _removeAd: (adKey) => {
179
+ set((state) => {
180
+ const newAds = new Map(state.ads);
181
+ const newLoadingKeys = new Set(state.loadingKeys);
182
+ const newErrors = new Map(state.errors);
183
+
184
+ newAds.delete(adKey);
185
+ newLoadingKeys.delete(adKey);
186
+ newErrors.delete(adKey);
187
+
188
+ return {
189
+ ads: newAds,
190
+ loadingKeys: newLoadingKeys,
191
+ errors: newErrors,
192
+ };
193
+ });
194
+ },
195
+
196
+ _setLoading: (adKey, loading) => {
197
+ set((state) => {
198
+ const newLoadingKeys = new Set(state.loadingKeys);
199
+ if (loading) {
200
+ newLoadingKeys.add(adKey);
201
+ } else {
202
+ newLoadingKeys.delete(adKey);
203
+ }
204
+ return { loadingKeys: newLoadingKeys };
205
+ });
206
+ },
207
+
208
+ _setError: (adKey, error) => {
209
+ set((state) => {
210
+ const newErrors = new Map(state.errors);
211
+ if (error) {
212
+ newErrors.set(adKey, error);
213
+ } else {
214
+ newErrors.delete(adKey);
215
+ }
216
+ return { errors: newErrors };
217
+ });
218
+ },
219
+
220
+ _clearError: (adKey) => {
221
+ set((state) => {
222
+ const newErrors = new Map(state.errors);
223
+ newErrors.delete(adKey);
224
+ return { errors: newErrors };
225
+ });
226
+ },
227
+ }))
228
+ );
229
+
230
+ // Setup native manager listeners để sync với Zustand store
231
+ let isListenerSetup = false;
232
+
233
+ const setupRewardedListeners = () => {
234
+ if (isListenerSetup) return;
235
+
236
+ rewardedAdsManager.on('adLoading', (ad: { adKey: string }) => {
237
+ useRewardedAdStore.getState()._setLoading(ad.adKey, true);
238
+ });
239
+
240
+ rewardedAdsManager.on('adLoaded', (ad: RewardedAdInstance) => {
241
+ useRewardedAdStore.getState()._updateAd(ad);
242
+ useRewardedAdStore.getState()._setLoading(ad.adKey, false);
243
+ useRewardedAdStore.getState()._clearError(ad.adKey);
244
+ });
245
+
246
+ rewardedAdsManager.on('adDisplayed', (ad: RewardedAdInstance) => {
247
+ useRewardedAdStore.getState()._updateAd(ad);
248
+ });
249
+
250
+ rewardedAdsManager.on('adOpened', (ad: RewardedAdInstance) => {
251
+ useRewardedAdStore.getState()._updateAd(ad);
252
+ });
253
+
254
+ rewardedAdsManager.on('adClicked', (ad: RewardedAdInstance) => {
255
+ useRewardedAdStore.getState()._updateAd(ad);
256
+ });
257
+
258
+ rewardedAdsManager.on('adClosed', (ad: RewardedAdInstance) => {
259
+ useRewardedAdStore.getState()._updateAd(ad);
260
+ });
261
+
262
+ rewardedAdsManager.on(
263
+ 'adEarnedReward',
264
+ ({ ad, _reward }: { ad: RewardedAdInstance; _reward: any }) => {
265
+ console.log(_reward);
266
+ useRewardedAdStore.getState()._updateAd(ad);
267
+ }
268
+ );
269
+
270
+ rewardedAdsManager.on('adError', (ad: RewardedAdInstance) => {
271
+ useRewardedAdStore.getState()._updateAd(ad);
272
+ useRewardedAdStore.getState()._setLoading(ad.adKey, false);
273
+ useRewardedAdStore
274
+ .getState()
275
+ ._setError(ad.adKey, ad.error || 'Unknown error');
276
+ });
277
+
278
+ rewardedAdsManager.on('adRemoved', (adKey: string) => {
279
+ useRewardedAdStore.getState()._removeAd(adKey);
280
+ });
281
+
282
+ rewardedAdsManager.on('allAdsCleared', () => {
283
+ useRewardedAdStore.getState().clearAllAds();
284
+ });
285
+
286
+ isListenerSetup = true;
287
+ };
288
+
289
+ // Initialize listeners
290
+ setupRewardedListeners();
@@ -0,0 +1,318 @@
1
+ import { create } from 'zustand';
2
+ import { subscribeWithSelector } from 'zustand/middleware';
3
+ import { rewardedInterstitialAdsManager } from '../ads-manager/RewardedInterstitialAdsManager';
4
+ import {
5
+ AdStatus,
6
+ type RewardedInterstitialAdInstance,
7
+ type RewardedInterstitialAdConfig,
8
+ } from '../types/ads-types';
9
+
10
+ interface RewardedInterstitialAdStore {
11
+ // State
12
+ ads: Map<string, RewardedInterstitialAdInstance>;
13
+ loadingKeys: Set<string>;
14
+ errors: Map<string, string>;
15
+
16
+ // Actions - CẬP NHẬT SIGNATURES
17
+ preloadAd: (config: RewardedInterstitialAdConfig) => Promise<void>;
18
+ loadAd: (config: RewardedInterstitialAdConfig) => Promise<void>;
19
+ displayAd: (
20
+ adKey: string
21
+ ) => Promise<{ ad: RewardedInterstitialAdInstance | null; reward: any }>;
22
+ removeAd: (adKey: string) => void;
23
+ refreshAd: (adKey: string) => Promise<void>;
24
+ clearAllAds: () => void;
25
+
26
+ // Getters
27
+ getAd: (adKey: string) => RewardedInterstitialAdInstance | null;
28
+ isLoading: (adKey: string) => boolean;
29
+ getError: (adKey: string) => string | null;
30
+ getAllAds: () => RewardedInterstitialAdInstance[];
31
+ getLoadedAds: () => RewardedInterstitialAdInstance[];
32
+ getErrorAds: () => RewardedInterstitialAdInstance[];
33
+ isUsingHighPriority: (adKey: string) => boolean; // THÊM MỚI
34
+ hasTriedHighPriority: (adKey: string) => boolean; // THÊM MỚI
35
+
36
+ // Internal actions
37
+ _updateAd: (ad: RewardedInterstitialAdInstance) => void;
38
+ _removeAd: (adKey: string) => void;
39
+ _setLoading: (adKey: string, loading: boolean) => void;
40
+ _setError: (adKey: string, error: string | null) => void;
41
+ _clearError: (adKey: string) => void;
42
+ }
43
+
44
+ export const useRewardedInterstitialAdStore =
45
+ create<RewardedInterstitialAdStore>()(
46
+ subscribeWithSelector((set, get) => ({
47
+ // Initial state
48
+ ads: new Map(),
49
+ loadingKeys: new Set(),
50
+ errors: new Map(),
51
+
52
+ // Public actions - CẬP NHẬT IMPLEMENTATIONS
53
+ preloadAd: async (config) => {
54
+ const { adKey } = config;
55
+ try {
56
+ get()._setLoading(adKey, true);
57
+ get()._clearError(adKey);
58
+
59
+ await rewardedInterstitialAdsManager.preloadAd(config);
60
+
61
+ const ad = rewardedInterstitialAdsManager.getAd(adKey);
62
+ if (ad) {
63
+ get()._updateAd(ad);
64
+ }
65
+ } catch (error) {
66
+ const errorMessage =
67
+ error instanceof Error ? error.message : String(error);
68
+ get()._setError(adKey, errorMessage);
69
+ console.error(
70
+ `Failed to preload rewarded interstitial ad ${adKey}:`,
71
+ errorMessage
72
+ );
73
+ } finally {
74
+ get()._setLoading(adKey, false);
75
+ }
76
+ },
77
+
78
+ loadAd: async (config) => {
79
+ return get().preloadAd(config);
80
+ },
81
+
82
+ displayAd: async (adKey) => {
83
+ try {
84
+ get()._clearError(adKey);
85
+
86
+ const result = await rewardedInterstitialAdsManager.displayAd(adKey);
87
+ if (result.ad) {
88
+ get()._updateAd(result.ad);
89
+ }
90
+ return result;
91
+ } catch (error) {
92
+ const errorMessage =
93
+ error instanceof Error ? error.message : String(error);
94
+ get()._setError(adKey, errorMessage);
95
+ console.error(
96
+ `Failed to display rewarded interstitial ad ${adKey}:`,
97
+ errorMessage
98
+ );
99
+ return { ad: null, reward: null };
100
+ }
101
+ },
102
+
103
+ removeAd: (adKey) => {
104
+ rewardedInterstitialAdsManager.removeAd(adKey);
105
+ get()._removeAd(adKey);
106
+ },
107
+
108
+ refreshAd: async (adKey) => {
109
+ try {
110
+ get()._setLoading(adKey, true);
111
+ get()._clearError(adKey);
112
+
113
+ await rewardedInterstitialAdsManager.refreshAd(adKey);
114
+
115
+ const ad = rewardedInterstitialAdsManager.getAd(adKey);
116
+ if (ad) {
117
+ get()._updateAd(ad);
118
+ }
119
+ } catch (error) {
120
+ const errorMessage =
121
+ error instanceof Error ? error.message : String(error);
122
+ get()._setError(adKey, errorMessage);
123
+ console.error(
124
+ `Failed to refresh rewarded interstitial ad ${adKey}:`,
125
+ errorMessage
126
+ );
127
+ } finally {
128
+ get()._setLoading(adKey, false);
129
+ }
130
+ },
131
+
132
+ clearAllAds: () => {
133
+ rewardedInterstitialAdsManager.clearAllAds();
134
+ set({
135
+ ads: new Map(),
136
+ loadingKeys: new Set(),
137
+ errors: new Map(),
138
+ });
139
+ },
140
+
141
+ // Getters
142
+ getAd: (adKey) => {
143
+ return get().ads.get(adKey) || null;
144
+ },
145
+
146
+ isLoading: (adKey) => {
147
+ return get().loadingKeys.has(adKey);
148
+ },
149
+
150
+ getError: (adKey) => {
151
+ return get().errors.get(adKey) || null;
152
+ },
153
+
154
+ getAllAds: () => {
155
+ return Array.from(get().ads.values());
156
+ },
157
+
158
+ getLoadedAds: () => {
159
+ return Array.from(get().ads.values()).filter(
160
+ (ad) => ad.status === AdStatus.LOADED
161
+ );
162
+ },
163
+
164
+ getErrorAds: () => {
165
+ return Array.from(get().ads.values()).filter(
166
+ (ad) => ad.status === AdStatus.ERROR
167
+ );
168
+ },
169
+
170
+ // THÊM MỚI
171
+ isUsingHighPriority: (adKey) => {
172
+ const ad = get().ads.get(adKey);
173
+ return ad?.isUsingHighPriority ?? false;
174
+ },
175
+
176
+ hasTriedHighPriority: (adKey) => {
177
+ const ad = get().ads.get(adKey);
178
+ return ad?.hasTriedHighPriority ?? false;
179
+ },
180
+
181
+ // Internal actions
182
+ _updateAd: (ad) => {
183
+ set((state) => ({
184
+ ads: new Map(state.ads.set(ad.adKey, ad)),
185
+ }));
186
+ },
187
+
188
+ _removeAd: (adKey) => {
189
+ set((state) => {
190
+ const newAds = new Map(state.ads);
191
+ const newLoadingKeys = new Set(state.loadingKeys);
192
+ const newErrors = new Map(state.errors);
193
+
194
+ newAds.delete(adKey);
195
+ newLoadingKeys.delete(adKey);
196
+ newErrors.delete(adKey);
197
+
198
+ return {
199
+ ads: newAds,
200
+ loadingKeys: newLoadingKeys,
201
+ errors: newErrors,
202
+ };
203
+ });
204
+ },
205
+
206
+ _setLoading: (adKey, loading) => {
207
+ set((state) => {
208
+ const newLoadingKeys = new Set(state.loadingKeys);
209
+ if (loading) {
210
+ newLoadingKeys.add(adKey);
211
+ } else {
212
+ newLoadingKeys.delete(adKey);
213
+ }
214
+ return { loadingKeys: newLoadingKeys };
215
+ });
216
+ },
217
+
218
+ _setError: (adKey, error) => {
219
+ set((state) => {
220
+ const newErrors = new Map(state.errors);
221
+ if (error) {
222
+ newErrors.set(adKey, error);
223
+ } else {
224
+ newErrors.delete(adKey);
225
+ }
226
+ return { errors: newErrors };
227
+ });
228
+ },
229
+
230
+ _clearError: (adKey) => {
231
+ set((state) => {
232
+ const newErrors = new Map(state.errors);
233
+ newErrors.delete(adKey);
234
+ return { errors: newErrors };
235
+ });
236
+ },
237
+ }))
238
+ );
239
+
240
+ // Setup native manager listeners để sync với Zustand store
241
+ let isListenerSetup = false;
242
+
243
+ const setupRewardedInterstitialListeners = () => {
244
+ if (isListenerSetup) return;
245
+
246
+ rewardedInterstitialAdsManager.on('adLoading', (ad: { adKey: string }) => {
247
+ useRewardedInterstitialAdStore.getState()._setLoading(ad.adKey, true);
248
+ });
249
+
250
+ rewardedInterstitialAdsManager.on(
251
+ 'adLoaded',
252
+ (ad: RewardedInterstitialAdInstance) => {
253
+ useRewardedInterstitialAdStore.getState()._updateAd(ad);
254
+ useRewardedInterstitialAdStore.getState()._setLoading(ad.adKey, false);
255
+ useRewardedInterstitialAdStore.getState()._clearError(ad.adKey);
256
+ }
257
+ );
258
+
259
+ rewardedInterstitialAdsManager.on(
260
+ 'adDisplayed',
261
+ (ad: RewardedInterstitialAdInstance) => {
262
+ useRewardedInterstitialAdStore.getState()._updateAd(ad);
263
+ }
264
+ );
265
+
266
+ rewardedInterstitialAdsManager.on(
267
+ 'adOpened',
268
+ (ad: RewardedInterstitialAdInstance) => {
269
+ useRewardedInterstitialAdStore.getState()._updateAd(ad);
270
+ }
271
+ );
272
+
273
+ rewardedInterstitialAdsManager.on(
274
+ 'adClicked',
275
+ (ad: RewardedInterstitialAdInstance) => {
276
+ useRewardedInterstitialAdStore.getState()._updateAd(ad);
277
+ }
278
+ );
279
+
280
+ rewardedInterstitialAdsManager.on(
281
+ 'adClosed',
282
+ (ad: RewardedInterstitialAdInstance) => {
283
+ useRewardedInterstitialAdStore.getState()._updateAd(ad);
284
+ }
285
+ );
286
+
287
+ rewardedInterstitialAdsManager.on(
288
+ 'adEarnedReward',
289
+ ({ ad, _reward }: { ad: RewardedInterstitialAdInstance; _reward: any }) => {
290
+ console.log(_reward);
291
+ useRewardedInterstitialAdStore.getState()._updateAd(ad);
292
+ }
293
+ );
294
+
295
+ rewardedInterstitialAdsManager.on(
296
+ 'adError',
297
+ (ad: RewardedInterstitialAdInstance) => {
298
+ useRewardedInterstitialAdStore.getState()._updateAd(ad);
299
+ useRewardedInterstitialAdStore.getState()._setLoading(ad.adKey, false);
300
+ useRewardedInterstitialAdStore
301
+ .getState()
302
+ ._setError(ad.adKey, ad.error || 'Unknown error');
303
+ }
304
+ );
305
+
306
+ rewardedInterstitialAdsManager.on('adRemoved', (adKey: string) => {
307
+ useRewardedInterstitialAdStore.getState()._removeAd(adKey);
308
+ });
309
+
310
+ rewardedInterstitialAdsManager.on('allAdsCleared', () => {
311
+ useRewardedInterstitialAdStore.getState().clearAllAds();
312
+ });
313
+
314
+ isListenerSetup = true;
315
+ };
316
+
317
+ // Initialize listeners
318
+ setupRewardedInterstitialListeners();