@upeex/ads-sdk 1.1.18 → 1.1.21

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 (3) hide show
  1. package/README.md +82 -10
  2. package/dist/index.js +35 -10
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -1,16 +1,88 @@
1
1
  # SDK-apps-React-native
2
- SDK para aplicaçõe React Native rodarem anúncios:
2
+ SDK oficial da Upeex para exibir anúncios em aplicativos React Native e Expo.
3
3
 
4
- # Comando para inciar
5
- npm i @upeex/ads-sdk
4
+ ## Instalação
6
5
 
7
- ### Como importar
6
+ Instale o pacote e suas dependências via npm:
8
7
 
9
- ```js
8
+ ```bash
9
+ npm install @upeex/ads-sdk
10
+ ```
11
+
12
+ ## Como Usar
13
+
14
+ ### Importação
15
+
16
+ ```javascript
10
17
  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
+ **Evite colocar dentro de:**
67
+ - Componentes que são desmontados condicionalmente (`{show && <AdBanner />}`).
68
+ - Headers ou Footers com `position: absolute` ou `zIndex` restritivo.
69
+
70
+ ### Props Disponíveis
71
+
72
+ | Prop | Tipo | Descrição |
73
+ |Data | --- | --- |
74
+ | `client` | `string` | **Obrigatório**. ID do cliente fornecido pela Upeex. |
75
+ | `slot` | `string` | **Obrigatório**. ID do slot (espaço) do anúncio. |
76
+ | `typeads` | `'banner' \| 'popup'` | Define o formato. Padrão é `'banner'`. |
77
+ | `theme` | `'light' \| 'dark'` | Define o tema (cores de fundo). Padrão `'light'`. |
78
+ | `baseUrl` | `string` | URL base da API (opcional). |
79
+ | `debug` | `boolean` | Ativa logs no console (avisa se o componente foi desmontado erradamente). |
80
+
81
+ ## Solução de Problemas
11
82
 
12
- // Carregar anúncio
13
- <AdBanner
14
- client="SEU_CLIENTE"
15
- slot="SEU_SLOT"
16
- /
83
+ - **Erro "Cannot find module 'react-native'"**: Certifique-se de que `react` e `react-native` estão instalados no seu projeto.
84
+ - **Popup não abre**:
85
+ 1. Verifique se `typeads="popup"`.
86
+ 2. Ative `debug={true}` e olhe o console. Se aparecer "Nenhum anúncio disponível", é normal.
87
+ 3. Se aparecer o aviso "O componente foi desmontado...", mova o `<AdBanner />` para a raiz da tela.
88
+ - **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.
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { jsx, jsxs } from 'react/jsx-runtime';
2
2
  import { useState, useEffect } from 'react';
3
- import { Platform, Dimensions, StyleSheet, View, Text, Modal, TouchableOpacity, Image, Linking } from 'react-native';
3
+ import { Platform, Dimensions, StyleSheet, View, Text, Modal, TouchableWithoutFeedback, TouchableOpacity, ActivityIndicator, Image, Linking } from 'react-native';
4
4
 
5
5
  async function getSignals() {
6
6
  var _a, _b, _c, _d, _e, _f;
@@ -114,7 +114,8 @@ style = {}, debug = false, }) {
114
114
  if (isPopup) {
115
115
  setModalVisible(true);
116
116
  }
117
- if (data.refresh && data.refresh > 0) {
117
+ // Only setup refresh if NOT a popup
118
+ if (!isPopup && data.refresh && data.refresh > 0) {
118
119
  log(`Refresh ativo: ${data.refresh}s`);
119
120
  refreshTimer = setTimeout(() => {
120
121
  log('Refazendo request do anúncio');
@@ -134,11 +135,27 @@ style = {}, debug = false, }) {
134
135
  return () => {
135
136
  if (refreshTimer)
136
137
  clearTimeout(refreshTimer);
138
+ if (isPopup && modalVisible && debug) {
139
+ 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.');
140
+ }
137
141
  };
138
- }, [client, slot, baseUrl, effectiveTypeAds]);
142
+ }, [client, slot, baseUrl, effectiveTypeAds, modalVisible]);
143
+ // Popup close delay logic
144
+ const [canClose, setCanClose] = useState(false);
145
+ useEffect(() => {
146
+ if (isPopup && modalVisible) {
147
+ setCanClose(false);
148
+ const timer = setTimeout(() => {
149
+ setCanClose(true);
150
+ }, 5000);
151
+ return () => clearTimeout(timer);
152
+ }
153
+ }, [isPopup, modalVisible]);
139
154
  const handlePress = () => {
140
155
  log('Clique no anúncio', ad.clickUrl);
141
156
  if (isPopup) {
157
+ // Allow close on click even if timer not finished?
158
+ // Usually ads allow clicking through immediately.
142
159
  setModalVisible(false);
143
160
  }
144
161
  if (!ad.clickUrl)
@@ -151,7 +168,9 @@ style = {}, debug = false, }) {
151
168
  }
152
169
  };
153
170
  const handleClose = () => {
154
- setModalVisible(false);
171
+ if (canClose) {
172
+ setModalVisible(false);
173
+ }
155
174
  };
156
175
  if (error) {
157
176
  return debug ? (jsx(View, { style: [styles.upeexContainer, styles.upeexDebug], children: jsx(Text, { style: styles.upeexDebugText, children: error }) })) : null;
@@ -160,11 +179,14 @@ style = {}, debug = false, }) {
160
179
  return debug ? (jsx(View, { style: [styles.upeexContainer, styles.upeexLoading], children: jsx(Text, { style: styles.upeexLoadingText, children: "Carregando an\u00FAncio\u2026" }) })) : null;
161
180
  }
162
181
  if (isPopup) {
163
- return (jsx(Modal, { transparent: true, visible: modalVisible, onRequestClose: handleClose, animationType: "fade", children: jsx(View, { style: styles.upeexOverlay, children: jsxs(View, { style: [styles.upeexPopupContainer, theme === 'dark' && styles.upeexDark], children: [jsx(TouchableOpacity, { onPress: handleClose, style: styles.upeexCloseButton, children: jsx(Text, { style: styles.upeexCloseText, children: "\u2715" }) }), jsx(TouchableOpacity, { activeOpacity: 0.9, onPress: handlePress, children: jsx(Image, { source: { uri: ad.image }, style: {
164
- width: ad.width || 300,
165
- height: ad.height || 300,
166
- resizeMode: 'contain',
167
- } }) })] }) }) }));
182
+ 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: [
183
+ styles.upeexPopupContainer,
184
+ theme === 'dark' && styles.upeexDark,
185
+ ], 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: {
186
+ width: Dimensions.get('window').width * 0.9,
187
+ height: Dimensions.get('window').height * 0.8,
188
+ resizeMode: 'contain',
189
+ } }) })] }) }) }) }) }));
168
190
  }
169
191
  return (jsx(TouchableOpacity, { activeOpacity: 0.9, style: [
170
192
  styles.upeexContainer,
@@ -205,6 +227,8 @@ const styles = StyleSheet.create({
205
227
  backgroundColor: 'rgba(0, 0, 0, 0.5)',
206
228
  justifyContent: 'center',
207
229
  alignItems: 'center',
230
+ zIndex: 9999,
231
+ elevation: 10,
208
232
  },
209
233
  upeexPopupContainer: {
210
234
  backgroundColor: '#fff',
@@ -212,11 +236,12 @@ const styles = StyleSheet.create({
212
236
  borderRadius: 10,
213
237
  alignItems: 'center',
214
238
  position: 'relative',
215
- elevation: 5,
239
+ elevation: 11,
216
240
  shadowColor: '#000',
217
241
  shadowOffset: { width: 0, height: 2 },
218
242
  shadowOpacity: 0.25,
219
243
  shadowRadius: 3.84,
244
+ zIndex: 10000,
220
245
  },
221
246
  upeexCloseButton: {
222
247
  position: 'absolute',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@upeex/ads-sdk",
3
- "version": "1.1.18",
3
+ "version": "1.1.21",
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",