@thead-vantage/react 2.19.0 → 2.20.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thead-vantage/react",
3
- "version": "2.19.0",
3
+ "version": "2.20.0",
4
4
  "description": "React components and utilities for TheAd Vantage ad platform integration",
5
5
  "main": "./src/index.ts",
6
6
  "module": "./src/index.ts",
@@ -35,6 +35,7 @@ export function AdBanner({
35
35
  const [devMode, setDevMode] = useState(false);
36
36
  const [impressionStatus, setImpressionStatus] = useState<'pending' | 'counting' | 'completed'>('pending');
37
37
  const impressionTimerRef = useRef<NodeJS.Timeout | null>(null);
38
+ const hasTrackedImpressionRef = useRef<string | null>(null); // Track which ad ID we've already tracked
38
39
 
39
40
  useEffect(() => {
40
41
  const loadAd = async () => {
@@ -70,23 +71,28 @@ export function AdBanner({
70
71
  setAd(response.ad);
71
72
  setDevMode(response.dev_mode || false);
72
73
 
73
- // Start impression timer if showImpressionFinished is enabled
74
- if (showImpressionFinished) {
75
- setImpressionStatus('counting');
76
- // Standard impression timer: 2 seconds of view time
77
- impressionTimerRef.current = setTimeout(() => {
78
- setImpressionStatus('completed');
79
- impressionTimerRef.current = null;
80
- }, 2000);
81
-
82
- // Track impression (will be skipped in dev mode)
83
- // Note: We don't wait for the API call to complete - the timer determines when to show green check
84
- trackImpression(response.ad.id, apiKey, apiUrl, impressionMetadata).catch(() => {
85
- // Silently handle tracking errors - timer will still complete
86
- });
87
- } else {
88
- // Track impression without timer UI
89
- trackImpression(response.ad.id, apiKey, apiUrl, impressionMetadata);
74
+ // Only track impression once per ad - check if we've already tracked this ad ID
75
+ if (hasTrackedImpressionRef.current !== response.ad.id) {
76
+ hasTrackedImpressionRef.current = response.ad.id;
77
+
78
+ // Start impression timer if showImpressionFinished is enabled
79
+ if (showImpressionFinished) {
80
+ setImpressionStatus('counting');
81
+ // Standard impression timer: 2 seconds of view time
82
+ impressionTimerRef.current = setTimeout(() => {
83
+ setImpressionStatus('completed');
84
+ impressionTimerRef.current = null;
85
+ }, 2000);
86
+
87
+ // Track impression (will be skipped in dev mode)
88
+ // Note: We don't wait for the API call to complete - the timer determines when to show green check
89
+ trackImpression(response.ad.id, apiKey, apiUrl, impressionMetadata).catch(() => {
90
+ // Silently handle tracking errors - timer will still complete
91
+ });
92
+ } else {
93
+ // Track impression without timer UI
94
+ trackImpression(response.ad.id, apiKey, apiUrl, impressionMetadata);
95
+ }
90
96
  }
91
97
  } else {
92
98
  // Create a more detailed error message
@@ -138,8 +144,11 @@ export function AdBanner({
138
144
  clearTimeout(impressionTimerRef.current);
139
145
  impressionTimerRef.current = null;
140
146
  }
147
+ // Reset impression tracking ref when component unmounts or key dependencies change
148
+ // This allows re-tracking if the ad ID changes (new ad loaded)
149
+ hasTrackedImpressionRef.current = null;
141
150
  };
142
- }, [platformId, apiKey, size, apiUrl, userId, userSegment, showImpressionFinished, impressionMetadata]);
151
+ }, [platformId, apiKey, size, apiUrl, userId, userSegment, showImpressionFinished]);
143
152
 
144
153
  const handleClick = () => {
145
154
  if (ad) {