@upeex/ads-sdk 1.1.24 → 1.1.25

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 (2) hide show
  1. package/dist/index.js +95 -49
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { jsx, jsxs } from 'react/jsx-runtime';
2
- import { useState, useEffect } from 'react';
3
- import { Platform, Dimensions, Animated, StyleSheet, Modal, View, TouchableOpacity, Image, Text, Linking } from 'react-native';
2
+ import { useState, useRef, useEffect } from 'react';
3
+ import { Platform, Dimensions, Animated, StyleSheet, Modal, View, ActivityIndicator, TouchableOpacity, Text, Image, Linking } from 'react-native';
4
4
 
5
5
  async function getSignals() {
6
6
  var _a, _b, _c, _d, _e, _f;
@@ -79,24 +79,42 @@ async function fetchAd({ baseUrl, client, slot, debug = false, typeAds, }) {
79
79
  return ad;
80
80
  }
81
81
 
82
- // Default fallback ads
82
+ // Default fallback ads shown when server returns an error
83
83
  const DEFAULT_POPUP_IMAGE = 'https://app.upeex.com.br/files/show/ads_square.jpeg';
84
84
  const DEFAULT_BANNER_IMAGE = 'https://app.upeex.com.br/files/show/ads_horizontal.jpg';
85
85
  const DEFAULT_CLICK_URL = 'https://upeex.com/';
86
86
  const { width: screenWidth, height: screenHeight } = Dimensions.get('window');
87
- // Workaround for TS2604
88
- Animated.View;
87
+ // Workaround for TS2604: JSX element type 'Animated.View' does not have any construct or call signatures.
88
+ const AnimatedView = Animated.View;
89
89
  function AdBanner({ client, slot, baseUrl = 'https://app.upeex.com.br/ad', theme = 'light', typeAds, typeads, style = {}, debug = false, }) {
90
90
  var _a;
91
91
  const [ad, setAd] = useState(null);
92
92
  const [error, setError] = useState(null);
93
93
  const [modalVisible, setModalVisible] = useState(false);
94
+ const [canClose, setCanClose] = useState(false);
95
+ const progressAnim = useRef(new Animated.Value(0)).current;
94
96
  const log = (...args) => {
95
97
  if (debug)
96
98
  console.log('[UPEEX ADS]', ...args);
97
99
  };
98
100
  const effectiveTypeAds = (_a = (typeAds || typeads)) === null || _a === void 0 ? void 0 : _a.toLowerCase();
99
101
  const isPopup = effectiveTypeAds === 'popup';
102
+ // Start 5-second progress bar when popup becomes visible
103
+ useEffect(() => {
104
+ if (modalVisible) {
105
+ setCanClose(false);
106
+ progressAnim.setValue(0);
107
+ Animated.timing(progressAnim, {
108
+ toValue: 1,
109
+ duration: 5000,
110
+ useNativeDriver: false,
111
+ }).start(({ finished }) => {
112
+ if (finished) {
113
+ setCanClose(true);
114
+ }
115
+ });
116
+ }
117
+ }, [modalVisible]);
100
118
  useEffect(() => {
101
119
  let refreshTimer;
102
120
  const load = async () => {
@@ -142,7 +160,7 @@ function AdBanner({ client, slot, baseUrl = 'https://app.upeex.com.br/ad', theme
142
160
  clearTimeout(refreshTimer);
143
161
  };
144
162
  }, [client, slot, baseUrl]);
145
- // ─── FALLBACK: show default ad on error ───────────────────────────────────
163
+ // ─── FALLBACK: default ad on error ────────────────────────────────────────
146
164
  if (error) {
147
165
  const fallbackImage = isPopup ? DEFAULT_POPUP_IMAGE : DEFAULT_BANNER_IMAGE;
148
166
  const handleFallbackPress = () => {
@@ -154,18 +172,27 @@ function AdBanner({ client, slot, baseUrl = 'https://app.upeex.com.br/ad', theme
154
172
  }
155
173
  };
156
174
  if (isPopup) {
157
- return (jsx(Modal, { transparent: true, animationType: "fade", visible: true, onRequestClose: () => { }, children: jsx(View, { style: styles.modalOverlay, children: jsx(View, { style: styles.modalContent, children: jsx(TouchableOpacity, { onPress: handleFallbackPress, activeOpacity: 0.9, children: jsx(Image, { source: { uri: fallbackImage }, style: styles.popupImage, resizeMode: "contain" }) }) }) }) }));
175
+ return (jsx(Modal, { transparent: true, animationType: "fade", visible: true, onRequestClose: () => { }, children: jsxs(View, { style: styles.modalBackground, children: [jsx(View, { style: styles.progressBarContainer, children: jsx(AnimatedView, { style: [
176
+ styles.progressBar,
177
+ {
178
+ width: progressAnim.interpolate({
179
+ inputRange: [0, 1],
180
+ outputRange: ['0%', '100%'],
181
+ }),
182
+ backgroundColor: '#fff',
183
+ },
184
+ ] }) }), !canClose && (jsx(View, { style: styles.spinnerOverlay, children: jsx(ActivityIndicator, { size: "small", color: "#fff" }) })), canClose && (jsx(TouchableOpacity, { style: styles.closeButton, onPress: () => { }, children: jsx(Text, { style: styles.closeButtonText, children: "X" }) })), jsx(TouchableOpacity, { style: styles.fullScreenTouch, activeOpacity: 1, onPress: handleFallbackPress, children: jsx(Image, { source: { uri: fallbackImage }, style: styles.fullScreenImage, resizeMode: "contain" }) })] }) }));
158
185
  }
159
186
  // Banner fallback
160
- return (jsx(TouchableOpacity, { activeOpacity: 0.9, style: [styles.upeexContainer, theme === 'dark' && styles.upeexDark, style], onPress: handleFallbackPress, children: jsx(Image, { source: { uri: fallbackImage }, style: styles.bannerFallbackImage, resizeMode: "contain" }) }));
187
+ return (jsx(TouchableOpacity, { activeOpacity: 0.9, style: [styles.container, theme === 'dark' && styles.dark, style], onPress: handleFallbackPress, children: jsx(Image, { source: { uri: fallbackImage }, style: { width: 320, height: 50, resizeMode: 'contain' } }) }));
161
188
  }
162
189
  // ──────────────────────────────────────────────────────────────────────────
163
190
  if (!ad) {
164
- return debug ? (jsx(View, { style: [styles.upeexContainer, styles.upeexLoading], children: jsx(Text, { style: styles.upeexLoadingText, children: "Carregando an\u00FAncio\u2026" }) })) : null;
191
+ return debug ? (jsx(View, { style: [styles.container, styles.loading], children: jsx(Text, { style: styles.loadingText, children: "Carregando an\u00FAncio\u2026" }) })) : null;
165
192
  }
166
193
  const handlePress = () => {
167
194
  log('Clique no anúncio', ad.clickUrl);
168
- if (isPopup) {
195
+ if (isPopup && canClose) {
169
196
  setModalVisible(false);
170
197
  }
171
198
  if (!ad.clickUrl)
@@ -179,81 +206,100 @@ function AdBanner({ client, slot, baseUrl = 'https://app.upeex.com.br/ad', theme
179
206
  };
180
207
  // ─── POPUP ─────────────────────────────────────────────────────────────────
181
208
  if (isPopup) {
182
- return (jsx(Modal, { transparent: true, animationType: "fade", visible: modalVisible, onRequestClose: () => setModalVisible(false), children: jsx(View, { style: styles.modalOverlay, children: jsxs(View, { style: styles.modalContent, children: [jsx(TouchableOpacity, { style: styles.modalClose, onPress: () => setModalVisible(false), children: jsx(Text, { style: styles.modalCloseText, children: "\u2715" }) }), jsx(TouchableOpacity, { onPress: handlePress, activeOpacity: 0.9, children: jsx(Image, { source: { uri: ad.image }, style: styles.popupImage, resizeMode: "contain" }) })] }) }) }));
209
+ return (jsx(Modal, { transparent: true, animationType: "fade", visible: modalVisible, onRequestClose: () => canClose && setModalVisible(false), children: jsxs(View, { style: styles.modalBackground, children: [jsx(View, { style: styles.progressBarContainer, children: jsx(AnimatedView, { style: [
210
+ styles.progressBar,
211
+ {
212
+ width: progressAnim.interpolate({
213
+ inputRange: [0, 1],
214
+ outputRange: ['0%', '100%'],
215
+ }),
216
+ backgroundColor: '#fff',
217
+ },
218
+ ] }) }), !canClose && (jsx(View, { style: styles.spinnerOverlay, children: jsx(ActivityIndicator, { size: "small", color: "#fff" }) })), canClose && (jsx(TouchableOpacity, { style: styles.closeButton, onPress: () => setModalVisible(false), children: jsx(Text, { style: styles.closeButtonText, children: "X" }) })), jsx(TouchableOpacity, { style: styles.fullScreenTouch, activeOpacity: 1, onPress: handlePress, children: jsx(Image, { source: { uri: ad.image }, style: styles.fullScreenImage, resizeMode: "contain" }) })] }) }));
183
219
  }
184
220
  // ─── BANNER ────────────────────────────────────────────────────────────────
185
- return (jsx(TouchableOpacity, { activeOpacity: 0.9, style: [
186
- styles.upeexContainer,
187
- theme === 'dark' && styles.upeexDark,
188
- style,
189
- ], onPress: handlePress, children: jsx(Image, { source: { uri: ad.image }, style: {
221
+ return (jsx(TouchableOpacity, { activeOpacity: 0.9, style: [styles.container, theme === 'dark' && styles.dark, style], onPress: handlePress, children: jsx(Image, { source: { uri: ad.image }, style: {
190
222
  width: ad.width || 320,
191
223
  height: ad.height || 50,
192
224
  resizeMode: 'contain',
193
225
  } }) }));
194
226
  }
195
227
  const styles = StyleSheet.create({
196
- upeexContainer: {
228
+ container: {
197
229
  backgroundColor: '#f2f2f2',
198
230
  padding: 8,
199
231
  alignItems: 'center',
200
232
  justifyContent: 'center',
201
233
  },
202
- upeexDark: {
234
+ dark: {
203
235
  backgroundColor: '#121212',
204
236
  },
205
- upeexLoading: {
237
+ loading: {
206
238
  backgroundColor: '#fafafa',
207
239
  },
208
- upeexLoadingText: {
240
+ loadingText: {
209
241
  fontSize: 11,
210
242
  color: '#999',
211
243
  },
212
- upeexDebug: {
244
+ debug: {
213
245
  backgroundColor: '#ffecec',
214
246
  },
215
- upeexDebugText: {
247
+ debugText: {
216
248
  fontSize: 11,
217
249
  color: '#c00',
218
250
  },
219
- bannerFallbackImage: {
220
- width: 320,
221
- height: 50,
222
- },
223
- // Modal / Popup styles
224
- modalOverlay: {
251
+ // Modal / Popup
252
+ modalBackground: {
225
253
  flex: 1,
226
- backgroundColor: 'rgba(0,0,0,0.6)',
254
+ backgroundColor: 'rgba(0,0,0,0.9)',
255
+ justifyContent: 'center',
227
256
  alignItems: 'center',
257
+ },
258
+ fullScreenTouch: {
259
+ flex: 1,
260
+ width: '100%',
261
+ height: '100%',
228
262
  justifyContent: 'center',
263
+ alignItems: 'center',
229
264
  },
230
- modalContent: {
231
- position: 'relative',
232
- borderRadius: 8,
233
- overflow: 'hidden',
265
+ fullScreenImage: {
266
+ width: '90%',
267
+ height: '90%',
234
268
  },
235
- modalClose: {
269
+ closeButton: {
236
270
  position: 'absolute',
237
- top: 8,
238
- right: 8,
239
- zIndex: 10,
240
- backgroundColor: 'rgba(0,0,0,0.5)',
241
- borderRadius: 16,
242
- width: 28,
243
- height: 28,
244
- alignItems: 'center',
271
+ top: 50,
272
+ right: 20,
273
+ backgroundColor: 'rgba(0,0,0,0.6)',
274
+ width: 40,
275
+ height: 40,
276
+ borderRadius: 20,
245
277
  justifyContent: 'center',
278
+ alignItems: 'center',
279
+ zIndex: 999,
246
280
  },
247
- modalCloseText: {
281
+ closeButtonText: {
248
282
  color: '#fff',
249
- fontSize: 14,
283
+ fontSize: 18,
250
284
  fontWeight: 'bold',
251
285
  },
252
- popupImage: {
253
- width: screenWidth * 0.85,
254
- height: screenWidth * 0.85,
255
- maxWidth: 400,
256
- maxHeight: 400,
286
+ progressBarContainer: {
287
+ position: 'absolute',
288
+ top: 0,
289
+ left: 0,
290
+ width: '100%',
291
+ height: 5,
292
+ backgroundColor: 'rgba(255,255,255,0.3)',
293
+ zIndex: 1000,
294
+ },
295
+ progressBar: {
296
+ height: '100%',
297
+ },
298
+ spinnerOverlay: {
299
+ position: 'absolute',
300
+ top: 12,
301
+ right: 20,
302
+ zIndex: 1000,
257
303
  },
258
304
  });
259
305
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@upeex/ads-sdk",
3
- "version": "1.1.24",
3
+ "version": "1.1.25",
4
4
  "description": "Upeex Ads SDK for React Native and universal apps",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",