@upeex/ads-sdk 1.1.23 → 1.1.24

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/README.md CHANGED
@@ -1,97 +1,16 @@
1
1
  # SDK-apps-React-native
2
- SDK oficial da Upeex para exibir anúncios em aplicativos React Native e Expo.
2
+ SDK para aplicaçõe React Native rodarem anúncios:
3
3
 
4
- ## Instalação
4
+ # Comando para inciar
5
+ npm i @upeex/ads-sdk
5
6
 
6
- Instale o pacote e suas dependências via npm:
7
+ ### Como importar
7
8
 
8
- ```bash
9
- npm install @upeex/ads-sdk
10
- ```
11
-
12
- ## Como Usar
13
-
14
- ### Importação
15
-
16
- ```javascript
9
+ ```js
17
10
  import AdBanner from '@upeex/ads-sdk';
18
- ```
19
-
20
- ### 1. Banner Simples (Padrão)
21
-
22
- Ideal para exibir em listas ou rodapés. O anúncio carrega no tamanho especificado ou padrão.
23
-
24
- ```javascript
25
- <AdBanner
26
- client="SEU_ID_CLIENTE"
27
- slot="SEU_ID_SLOT"
28
- />
29
- ```
30
-
31
- ### 2. Anúncio Popup (Modal)
32
-
33
- Exibe um anúncio em tela cheia (modal) sobrepondo o conteúdo.
34
- **Comportamento:**
35
- - Abre automaticamente se houver anúncio disponível.
36
- - **Bloqueio de 5 segundos:** O usuário deve aguardar 5 segundos antes de fechar.
37
- - **Spinner:** Um indicador de carregamento aparece durante o bloqueio.
38
- - **Sem Auto-Refresh:** O popup carrega apenas uma vez.
39
- - **Visual:** Ocupa toda a tela (transparente na StatusBar) e a imagem é redimensionada para 90% da largura.
40
-
41
- #### ⚠️ Onde Colocar o Popup (Importante!)
42
-
43
- Para garantir que o popup abra corretamente e não sobreponha outros Modals de forma errada, **coloque o componente no final do seu container principal**, logo antes de fechar a view da tela.
44
-
45
- **Exemplo Correto:**
46
-
47
- ```javascript
48
- return (
49
- <View style={{ flex: 1 }}> {/* Seu Container Principal (View, SafeAreaView, etc) */}
50
- <Header />
51
- <Conteudo />
52
-
53
- {/* Outros Modals do seu App */}
54
- <Modal visible={isLoading}>...</Modal>
55
-
56
- {/* ✅ COLOCAR AQUI, NO FINAL: */}
57
- <AdBanner
58
- client="SEU_ID_CLIENTE"
59
- slot="SEU_ID_SLOT"
60
- typeads="popup"
61
- />
62
- </View>
63
- );
64
- ```
65
-
66
- ```
67
-
68
- **Evite colocar dentro de:**
69
- - Componentes que são desmontados condicionalmente (`{show && <AdBanner />}`).
70
- - Headers ou Footers com `position: absolute` ou `zIndex` restritivo.
71
-
72
- #### ⚠️ Conflito com Outros Modals (Loading, Alertas)
73
-
74
- O React Native pode ter problemas ao tentar exibir **dois Modals ao mesmo tempo** (ex: um Loading Spinner e o Anúncio Popup).
75
- - Se o seu app abre um Modal de "Carregando..." ao entrar na tela, aguarde ele fechar antes de renderizar o anúncio, ou use o anúncio como o próprio loading inicial.
76
- - O SDK possui `zIndex` alto (9999), mas o sistema operacional (especialmente Android) pode priorizar o último Modal aberto na árvore de componentes.
77
-
78
-
79
- ### Props Disponíveis
80
-
81
- | Prop | Tipo | Descrição |
82
- |Data | --- | --- |
83
- | `client` | `string` | **Obrigatório**. ID do cliente fornecido pela Upeex. |
84
- | `slot` | `string` | **Obrigatório**. ID do slot (espaço) do anúncio. |
85
- | `typeads` | `'banner' \| 'popup'` | Define o formato. Padrão é `'banner'`. |
86
- | `theme` | `'light' \| 'dark'` | Define o tema (cores de fundo). Padrão `'light'`. |
87
- | `baseUrl` | `string` | URL base da API (opcional). |
88
- | `debug` | `boolean` | Ativa logs no console (avisa se o componente foi desmontado erradamente). |
89
-
90
- ## Solução de Problemas
91
11
 
92
- - **Erro "Cannot find module 'react-native'"**: Certifique-se de que `react` e `react-native` estão instalados no seu projeto.
93
- - **Popup não abre**:
94
- 1. Verifique se `typeads="popup"`.
95
- 2. Ative `debug={true}` e olhe o console. Se aparecer "Nenhum anúncio disponível", é normal.
96
- 3. Se aparecer o aviso "O componente foi desmontado...", mova o `<AdBanner />` para a raiz da tela.
97
- - **Sobreposição**: O popup possui `zIndex: 9999` e `elevation: 11`. Se ainda estiver atrás de algum elemento, verifique se o pai não tem um `zIndex` maior.
12
+ // Carregar anúncio
13
+ <AdBanner
14
+ client="SEU_CLIENTE"
15
+ slot="SEU_SLOT"
16
+ /
@@ -8,6 +8,5 @@ type Props = {
8
8
  style?: object;
9
9
  debug?: boolean;
10
10
  };
11
- export default function AdBanner({ client, slot, baseUrl, theme, typeAds, typeads, // Receive alias
12
- style, debug, }: Props): any;
11
+ export default function AdBanner({ client, slot, baseUrl, theme, typeAds, typeads, style, debug, }: Props): import("react/jsx-runtime").JSX.Element;
13
12
  export {};
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { jsx, jsxs } from 'react/jsx-runtime';
2
- import React, { useState, useEffect } from 'react';
3
- import { Platform, Dimensions, StyleSheet, View, Text, Modal, TouchableWithoutFeedback, TouchableOpacity, ActivityIndicator, Image, Linking } from 'react-native';
2
+ import { useState, useEffect } from 'react';
3
+ import { Platform, Dimensions, Animated, StyleSheet, Modal, View, TouchableOpacity, Image, Text, Linking } from 'react-native';
4
4
 
5
5
  async function getSignals() {
6
6
  var _a, _b, _c, _d, _e, _f;
@@ -79,8 +79,14 @@ async function fetchAd({ baseUrl, client, slot, debug = false, typeAds, }) {
79
79
  return ad;
80
80
  }
81
81
 
82
- function AdBanner({ client, slot, baseUrl = 'https://app.upeex.com.br/ad', theme = 'light', typeAds, typeads, // Receive alias
83
- style = {}, debug = false, }) {
82
+ // Default fallback ads
83
+ const DEFAULT_POPUP_IMAGE = 'https://app.upeex.com.br/files/show/ads_square.jpeg';
84
+ const DEFAULT_BANNER_IMAGE = 'https://app.upeex.com.br/files/show/ads_horizontal.jpg';
85
+ const DEFAULT_CLICK_URL = 'https://upeex.com/';
86
+ const { width: screenWidth, height: screenHeight } = Dimensions.get('window');
87
+ // Workaround for TS2604
88
+ Animated.View;
89
+ function AdBanner({ client, slot, baseUrl = 'https://app.upeex.com.br/ad', theme = 'light', typeAds, typeads, style = {}, debug = false, }) {
84
90
  var _a;
85
91
  const [ad, setAd] = useState(null);
86
92
  const [error, setError] = useState(null);
@@ -91,11 +97,6 @@ style = {}, debug = false, }) {
91
97
  };
92
98
  const effectiveTypeAds = (_a = (typeAds || typeads)) === null || _a === void 0 ? void 0 : _a.toLowerCase();
93
99
  const isPopup = effectiveTypeAds === 'popup';
94
- // Track visibility with ref to avoid dependency loops in useEffect
95
- const isVisibleRef = React.useRef(false);
96
- useEffect(() => {
97
- isVisibleRef.current = modalVisible;
98
- }, [modalVisible]);
99
100
  useEffect(() => {
100
101
  let refreshTimer;
101
102
  const load = async () => {
@@ -119,8 +120,7 @@ style = {}, debug = false, }) {
119
120
  if (isPopup) {
120
121
  setModalVisible(true);
121
122
  }
122
- // Only setup refresh if NOT a popup
123
- if (!isPopup && data.refresh && data.refresh > 0) {
123
+ if (data.refresh && data.refresh > 0) {
124
124
  log(`Refresh ativo: ${data.refresh}s`);
125
125
  refreshTimer = setTimeout(() => {
126
126
  log('Refazendo request do anúncio');
@@ -140,27 +140,32 @@ style = {}, debug = false, }) {
140
140
  return () => {
141
141
  if (refreshTimer)
142
142
  clearTimeout(refreshTimer);
143
- if (isPopup && isVisibleRef.current && debug) {
144
- console.warn('[UPEEX ADS] Aviso: O componente AdBanner (Popup) foi desmontado enquanto estava visível. Verifique se ele não está dentro de uma View que foi ocultada ou removida da tela.');
143
+ };
144
+ }, [client, slot, baseUrl]);
145
+ // ─── FALLBACK: show default ad on error ───────────────────────────────────
146
+ if (error) {
147
+ const fallbackImage = isPopup ? DEFAULT_POPUP_IMAGE : DEFAULT_BANNER_IMAGE;
148
+ const handleFallbackPress = () => {
149
+ if (Platform.OS === 'web') {
150
+ window.open(DEFAULT_CLICK_URL, '_blank');
151
+ }
152
+ else {
153
+ Linking.openURL(DEFAULT_CLICK_URL);
145
154
  }
146
155
  };
147
- }, [client, slot, baseUrl, effectiveTypeAds]); // Removed modalVisible to prevent loops
148
- // Popup close delay logic
149
- const [canClose, setCanClose] = useState(false);
150
- useEffect(() => {
151
- if (isPopup && modalVisible) {
152
- setCanClose(false);
153
- const timer = setTimeout(() => {
154
- setCanClose(true);
155
- }, 5000);
156
- return () => clearTimeout(timer);
156
+ 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" }) }) }) }) }));
157
158
  }
158
- }, [isPopup, modalVisible]);
159
+ // 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" }) }));
161
+ }
162
+ // ──────────────────────────────────────────────────────────────────────────
163
+ if (!ad) {
164
+ return debug ? (jsx(View, { style: [styles.upeexContainer, styles.upeexLoading], children: jsx(Text, { style: styles.upeexLoadingText, children: "Carregando an\u00FAncio\u2026" }) })) : null;
165
+ }
159
166
  const handlePress = () => {
160
167
  log('Clique no anúncio', ad.clickUrl);
161
168
  if (isPopup) {
162
- // Allow close on click even if timer not finished?
163
- // Usually ads allow clicking through immediately.
164
169
  setModalVisible(false);
165
170
  }
166
171
  if (!ad.clickUrl)
@@ -172,27 +177,11 @@ style = {}, debug = false, }) {
172
177
  Linking.openURL(ad.clickUrl);
173
178
  }
174
179
  };
175
- const handleClose = () => {
176
- if (canClose) {
177
- setModalVisible(false);
178
- }
179
- };
180
- if (error) {
181
- return debug ? (jsx(View, { style: [styles.upeexContainer, styles.upeexDebug], children: jsx(Text, { style: styles.upeexDebugText, children: error }) })) : null;
182
- }
183
- if (!ad) {
184
- return debug ? (jsx(View, { style: [styles.upeexContainer, styles.upeexLoading], children: jsx(Text, { style: styles.upeexLoadingText, children: "Carregando an\u00FAncio\u2026" }) })) : null;
185
- }
180
+ // ─── POPUP ─────────────────────────────────────────────────────────────────
186
181
  if (isPopup) {
187
- return (jsx(Modal, { transparent: true, visible: modalVisible, onRequestClose: handleClose, animationType: "fade", statusBarTranslucent: true, hardwareAccelerated: true, children: jsx(TouchableWithoutFeedback, { onPress: handleClose, children: jsx(View, { style: styles.upeexOverlay, children: jsx(TouchableWithoutFeedback, { onPress: () => { }, children: jsxs(View, { style: [
188
- styles.upeexPopupContainer,
189
- theme === 'dark' && styles.upeexDark,
190
- ], children: [canClose ? (jsx(TouchableOpacity, { onPress: handleClose, style: styles.upeexCloseButton, children: jsx(Text, { style: styles.upeexCloseText, children: "\u2715" }) })) : (jsx(View, { style: styles.upeexCloseButton, children: jsx(ActivityIndicator, { size: "small", color: "#999" }) })), jsx(TouchableOpacity, { activeOpacity: 0.9, onPress: handlePress, children: jsx(Image, { source: { uri: ad.image }, style: {
191
- width: Dimensions.get('window').width * 0.9,
192
- height: Dimensions.get('window').height * 0.8,
193
- resizeMode: 'contain',
194
- } }) })] }) }) }) }) }));
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" }) })] }) }) }));
195
183
  }
184
+ // ─── BANNER ────────────────────────────────────────────────────────────────
196
185
  return (jsx(TouchableOpacity, { activeOpacity: 0.9, style: [
197
186
  styles.upeexContainer,
198
187
  theme === 'dark' && styles.upeexDark,
@@ -227,38 +216,44 @@ const styles = StyleSheet.create({
227
216
  fontSize: 11,
228
217
  color: '#c00',
229
218
  },
230
- upeexOverlay: {
219
+ bannerFallbackImage: {
220
+ width: 320,
221
+ height: 50,
222
+ },
223
+ // Modal / Popup styles
224
+ modalOverlay: {
231
225
  flex: 1,
232
- backgroundColor: 'rgba(0, 0, 0, 0.5)',
233
- justifyContent: 'center',
226
+ backgroundColor: 'rgba(0,0,0,0.6)',
234
227
  alignItems: 'center',
235
- zIndex: 9999,
236
- elevation: 10,
228
+ justifyContent: 'center',
237
229
  },
238
- upeexPopupContainer: {
239
- backgroundColor: 'transparent',
240
- padding: 0,
241
- alignItems: 'center',
230
+ modalContent: {
242
231
  position: 'relative',
243
- zIndex: 10000,
232
+ borderRadius: 8,
233
+ overflow: 'hidden',
244
234
  },
245
- upeexCloseButton: {
235
+ modalClose: {
246
236
  position: 'absolute',
247
- top: -10,
248
- right: -10,
249
- zIndex: 1,
250
- backgroundColor: '#fff',
251
- borderRadius: 15,
252
- width: 30,
253
- height: 30,
254
- justifyContent: 'center',
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,
255
244
  alignItems: 'center',
256
- elevation: 5,
245
+ justifyContent: 'center',
257
246
  },
258
- upeexCloseText: {
259
- fontSize: 18,
247
+ modalCloseText: {
248
+ color: '#fff',
249
+ fontSize: 14,
260
250
  fontWeight: 'bold',
261
- color: '#333',
251
+ },
252
+ popupImage: {
253
+ width: screenWidth * 0.85,
254
+ height: screenWidth * 0.85,
255
+ maxWidth: 400,
256
+ maxHeight: 400,
262
257
  },
263
258
  });
264
259
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@upeex/ads-sdk",
3
- "version": "1.1.23",
3
+ "version": "1.1.24",
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",
@@ -27,10 +27,11 @@
27
27
  "author": "Upeex",
28
28
  "license": "MIT",
29
29
  "dependencies": {
30
- "@upeex/ads-sdk": "^1.1.10",
31
30
  "expo-localization": "^17.0.8"
32
31
  },
33
32
  "devDependencies": {
33
+ "@types/react": "^19.2.13",
34
+ "@types/react-native": "^0.73.0",
34
35
  "rollup": "^4.57.0",
35
36
  "rollup-plugin-typescript2": "^0.36.0",
36
37
  "tslib": "^2.8.1",