@inngageregistry/inngage-react 4.0.0-beta.1 → 4.0.0-beta.2
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 +32 -11
- package/package.json +1 -1
- package/src/components/in_app.tsx +42 -9
- package/src/components/styles.ts +31 -13
- package/src/firebase/notifications_listener.ts +42 -6
- package/src/index.ts +6 -3
package/README.md
CHANGED
|
@@ -18,23 +18,44 @@
|
|
|
18
18
|
</div>
|
|
19
19
|
|
|
20
20
|
## Instalação
|
|
21
|
-
###
|
|
21
|
+
### Ambiente de desenvolvimento
|
|
22
|
+
Antes de começar a utilizar nossa SDK, instale as dependências externas utilizadas:
|
|
22
23
|
```bash
|
|
23
24
|
"dependencies": {
|
|
24
25
|
"@react-native-async-storage/async-storage": "^1.18.1",
|
|
26
|
+
"@react-native-community/push-notification-ios": "^1.11.0",
|
|
25
27
|
"@react-native-firebase/app": "^17.4.2",
|
|
26
28
|
"@react-native-firebase/messaging": "^17.4.2",
|
|
27
29
|
"react-native-device-info": "^10.6.0",
|
|
28
|
-
"react-native-inappbrowser-reborn": "^3.7.0",
|
|
29
30
|
"react-native-localize": "^2.2.6",
|
|
30
|
-
"react-native-
|
|
31
|
+
"react-native-permissions": "^3.8.0",
|
|
32
|
+
"react-native-push-notification": "^8.1.1",
|
|
33
|
+
"react-native-inappbrowser-reborn": "^3.7.0",
|
|
31
34
|
}
|
|
32
35
|
```
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
36
|
+
> 📘 *Recomendação*: Certifique-se de instalar as versões conforme especificado nesta documentação. Para a dependência react-native-inappbrowser-reborn, siga as instruções da seção "Getting Started" na documentação oficial para garantir o funcionamento adequado na abertura de URLs do tipo Weblink. Consulte o link a seguir para mais detalhes:
|
|
37
|
+
>
|
|
38
|
+
> <https://www.npmjs.com/package/react-native-inappbrowser-reborn>
|
|
39
|
+
|
|
40
|
+
### Importando o FCM Token (API Key)
|
|
41
|
+
Para aproveitar nossa SDK, será necessário importar o FCM Token (API Key) do seu projeto Firebase em nossa plataforma. Siga o passo a passo neste [link]("https://inngage.readme.io/docs/firebase-console#configura%C3%A7%C3%B5es-do-projeto-firebase") para executar essa ação.
|
|
42
|
+
|
|
43
|
+
### Instalando o package utilizando o NPM ou YARN
|
|
44
|
+
|
|
45
|
+
Para adicionar a SDK da Inngage ao seu projeto, execute o seguinte comando utilizando o NPM:
|
|
46
|
+
```
|
|
47
|
+
npm i @inngageregistry/inngage-react
|
|
48
|
+
```
|
|
49
|
+
Este comando adiciona a seguinte linha no arquivo _package.json_ de seu pacote:
|
|
50
|
+
```
|
|
51
|
+
"dependencies": {
|
|
52
|
+
"@inngageregistry/inngage-react": "^4.0.0-beta.2",
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
> 📘 Se a instalação via `npm` não funcionar corretamente, você pode instalar a dependência utilizando o `yarn`.
|
|
56
|
+
> 📘
|
|
57
|
+
|
|
58
|
+
Para instalar a SDK com o yarn, siga os passos abaixo:
|
|
59
|
+
|
|
60
|
+
1. No arquivo `package.json`, adicione a seguinte dependência em `dependencies`: **"@inngageregistry/inngage-react": "^4.0.0-beta.2"**.
|
|
61
|
+
2. No terminal, dentro da pasta do seu projeto, execute o comando: **yarn install**. Isso irá instalar a SDK corretamente.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inngageregistry/inngage-react",
|
|
3
|
-
"version": "4.0.0-beta.
|
|
3
|
+
"version": "4.0.0-beta.2",
|
|
4
4
|
"description": "Inngage Plugin for React Native applications for marketing campaign optimization using Push Notification.",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"types": "src/index.d.ts",
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
TouchableOpacity,
|
|
8
8
|
ImageBackground,
|
|
9
9
|
Dimensions,
|
|
10
|
+
Linking,
|
|
10
11
|
} from "react-native";
|
|
11
12
|
|
|
12
13
|
import AsyncStorage from "@react-native-async-storage/async-storage";
|
|
@@ -16,6 +17,8 @@ import { buildStyles } from "./styles";
|
|
|
16
17
|
import { Modal } from "../components/modal";
|
|
17
18
|
import { InngageProperties } from "../models/inngage_properties";
|
|
18
19
|
|
|
20
|
+
import InAppBrowser from 'react-native-inappbrowser-reborn';
|
|
21
|
+
|
|
19
22
|
interface InAppData {
|
|
20
23
|
inapp_message: boolean
|
|
21
24
|
title: string
|
|
@@ -69,6 +72,7 @@ export function InApp({ onDismiss }: InAppProps): JSX.Element {
|
|
|
69
72
|
try {
|
|
70
73
|
console.log('in app message')
|
|
71
74
|
const data = await AsyncStorage.getItem('inapp');
|
|
75
|
+
console.log(data)
|
|
72
76
|
if (data) {
|
|
73
77
|
const parsedData = JSON.parse(data);
|
|
74
78
|
const richContentData = parsedData.rich_content;
|
|
@@ -93,6 +97,30 @@ export function InApp({ onDismiss }: InAppProps): JSX.Element {
|
|
|
93
97
|
onDismiss();
|
|
94
98
|
}
|
|
95
99
|
|
|
100
|
+
const handleClick = async (link, type) => {
|
|
101
|
+
if (type === 'inapp') {
|
|
102
|
+
try {
|
|
103
|
+
if (await InAppBrowser.isAvailable()) {
|
|
104
|
+
await InAppBrowser.open(link, {
|
|
105
|
+
dismissButtonStyle: 'close',
|
|
106
|
+
preferredBarTintColor: '#453AA4',
|
|
107
|
+
preferredControlTintColor: 'white',
|
|
108
|
+
enableDefaultShare: true,
|
|
109
|
+
enableBarCollapsing: true,
|
|
110
|
+
});
|
|
111
|
+
} else {
|
|
112
|
+
Linking.openURL(link);
|
|
113
|
+
}
|
|
114
|
+
} catch (error) {
|
|
115
|
+
console.error(error);
|
|
116
|
+
}
|
|
117
|
+
} else if (type === 'deep') {
|
|
118
|
+
Linking.openURL(link).catch((err) =>
|
|
119
|
+
console.error('Erro ao abrir o link:', err)
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
|
|
96
124
|
const imageUrls: string[] = [
|
|
97
125
|
richContent?.img1 ?? '',
|
|
98
126
|
richContent?.img2 ?? '',
|
|
@@ -126,6 +154,7 @@ export function InApp({ onDismiss }: InAppProps): JSX.Element {
|
|
|
126
154
|
|
|
127
155
|
return (
|
|
128
156
|
<Modal
|
|
157
|
+
onBackdropPress={handleDismissInApp}
|
|
129
158
|
renderToHardwareTextureAndroid={true}
|
|
130
159
|
transparent={true}
|
|
131
160
|
visible={visible}>
|
|
@@ -137,21 +166,25 @@ export function InApp({ onDismiss }: InAppProps): JSX.Element {
|
|
|
137
166
|
itemWidth={itemWidth}
|
|
138
167
|
renderItem={_renderItem} /> : null}
|
|
139
168
|
<TouchableOpacity style={styles.closeButton} onPress={handleDismissInApp}>
|
|
140
|
-
<Text>X</Text>
|
|
169
|
+
<Text style={styles.textButton}>X</Text>
|
|
141
170
|
</TouchableOpacity>
|
|
142
171
|
<View style={styles.messageData}>
|
|
143
172
|
<Text style={styles.title}>{data?.title}</Text>
|
|
144
173
|
<Text style={styles.body}>{data?.body}</Text>
|
|
145
174
|
</View>
|
|
146
175
|
<View style={styles.footer}>
|
|
147
|
-
{data?.btn_left_txt != null ?
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
176
|
+
{data?.btn_left_txt != null ?
|
|
177
|
+
<TouchableOpacity
|
|
178
|
+
style={styles.buttonLeft}
|
|
179
|
+
onPress={() => handleClick(data?.btn_left_action_link, data?.btn_left_action_type)}>
|
|
180
|
+
<Text style={styles.textButtonLeft}>{data?.btn_left_txt}</Text>
|
|
181
|
+
</TouchableOpacity> : null}
|
|
182
|
+
{data?.btn_right_txt != null ?
|
|
183
|
+
<TouchableOpacity
|
|
184
|
+
style={styles.buttonRight}
|
|
185
|
+
onPress={() => handleClick(data?.btn_right_action_link, data?.btn_right_action_type)}>
|
|
186
|
+
<Text style={styles.textButtonRight}>{data?.btn_right_txt}</Text>
|
|
187
|
+
</TouchableOpacity> : null}
|
|
155
188
|
</View>
|
|
156
189
|
</ImageBackground>
|
|
157
190
|
</Modal>
|
package/src/components/styles.ts
CHANGED
|
@@ -3,15 +3,29 @@ import { PlatformColor, StyleSheet } from "react-native";
|
|
|
3
3
|
|
|
4
4
|
export const buildStyles = (data: any, screen: any) => StyleSheet.create({
|
|
5
5
|
closeButton: {
|
|
6
|
+
width: 30,
|
|
7
|
+
height: 30,
|
|
8
|
+
justifyContent: 'center',
|
|
9
|
+
alignItems: 'center',
|
|
10
|
+
backgroundColor: 'transparent', // Cor do botão
|
|
11
|
+
borderRadius: 25, // Torna o botão circular
|
|
12
|
+
shadowOffset: { width: 0, height: 2 },
|
|
13
|
+
shadowOpacity: 0.2,
|
|
14
|
+
shadowRadius: 4,
|
|
6
15
|
position: 'absolute',
|
|
7
16
|
top: 10,
|
|
8
17
|
right: 10,
|
|
9
18
|
zIndex: 10,
|
|
10
19
|
},
|
|
20
|
+
textButton: {
|
|
21
|
+
color: '#000', // Cor do texto "X"
|
|
22
|
+
fontSize: 16, // Tamanho do "X"
|
|
23
|
+
fontWeight: 'bold', // Deixa o "X" em negrito
|
|
24
|
+
},
|
|
11
25
|
content: {
|
|
12
26
|
backgroundColor: data?.background_color,
|
|
13
27
|
flexDirection: "column",
|
|
14
|
-
borderRadius:
|
|
28
|
+
borderRadius: 20,
|
|
15
29
|
paddingBottom: 16,
|
|
16
30
|
paddingRight: 16,
|
|
17
31
|
paddingLeft: 16,
|
|
@@ -21,7 +35,11 @@ export const buildStyles = (data: any, screen: any) => StyleSheet.create({
|
|
|
21
35
|
width: screen,
|
|
22
36
|
alignItems: "center"
|
|
23
37
|
},
|
|
24
|
-
messageData: {
|
|
38
|
+
messageData: {
|
|
39
|
+
marginTop: 12,
|
|
40
|
+
alignItems: "center",
|
|
41
|
+
justifyContent: "center",
|
|
42
|
+
},
|
|
25
43
|
footer: {
|
|
26
44
|
flexDirection: "row",
|
|
27
45
|
alignItems: "center",
|
|
@@ -29,16 +47,12 @@ export const buildStyles = (data: any, screen: any) => StyleSheet.create({
|
|
|
29
47
|
marginTop: 4,
|
|
30
48
|
},
|
|
31
49
|
title: {
|
|
32
|
-
color:
|
|
33
|
-
`@android:color/${"primary_text_light"}`
|
|
34
|
-
),
|
|
50
|
+
color: data?.title_font_color,
|
|
35
51
|
fontWeight: "500",
|
|
36
52
|
fontSize: 18,
|
|
37
53
|
},
|
|
38
54
|
body: {
|
|
39
|
-
color:
|
|
40
|
-
`@android:color/${"secondary_text_light"}`
|
|
41
|
-
),
|
|
55
|
+
color: data?.body_font_color,
|
|
42
56
|
fontSize: 16,
|
|
43
57
|
marginTop: 10,
|
|
44
58
|
marginBottom: 10,
|
|
@@ -57,14 +71,18 @@ export const buildStyles = (data: any, screen: any) => StyleSheet.create({
|
|
|
57
71
|
justifyContent: "center",
|
|
58
72
|
alignItems: "center",
|
|
59
73
|
},
|
|
60
|
-
|
|
61
|
-
color:
|
|
62
|
-
|
|
63
|
-
|
|
74
|
+
textButtonLeft: {
|
|
75
|
+
color: data?.btn_left_txt_color,
|
|
76
|
+
textAlign: "center",
|
|
77
|
+
backgroundColor: "transparent",
|
|
78
|
+
padding: 8,
|
|
79
|
+
fontSize: 14,
|
|
80
|
+
},
|
|
81
|
+
textButtonRight: {
|
|
82
|
+
color: data?.btn_right_txt_color,
|
|
64
83
|
textAlign: "center",
|
|
65
84
|
backgroundColor: "transparent",
|
|
66
85
|
padding: 8,
|
|
67
86
|
fontSize: 14,
|
|
68
|
-
textTransform: "uppercase",
|
|
69
87
|
},
|
|
70
88
|
})
|
|
@@ -3,11 +3,13 @@ import { useEffect, useState } from 'react';
|
|
|
3
3
|
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
4
4
|
|
|
5
5
|
import messaging from '@react-native-firebase/messaging';
|
|
6
|
+
import PushNotificationIOS from "@react-native-community/push-notification-ios";
|
|
6
7
|
import PushNotification, { Importance } from 'react-native-push-notification'
|
|
7
8
|
|
|
8
9
|
import { InngageProperties } from '../models/inngage_properties';
|
|
9
10
|
import * as ApiService from '../services/api_services'
|
|
10
|
-
import { AppState } from 'react-native';
|
|
11
|
+
import { AppState, Linking } from 'react-native';
|
|
12
|
+
import InAppBrowser from 'react-native-inappbrowser-reborn';
|
|
11
13
|
|
|
12
14
|
export const messagingHeadlessTask = () => {
|
|
13
15
|
return messaging().setBackgroundMessageHandler(async remoteMessage => {
|
|
@@ -50,12 +52,20 @@ export const useInAppHandler = () => {
|
|
|
50
52
|
}
|
|
51
53
|
|
|
52
54
|
export const InngageNotificationMessage = (firebaseListenCallback?: any) => {
|
|
55
|
+
const [notificationMessage, setNotificationMessage] = useState(null);
|
|
56
|
+
|
|
53
57
|
useEffect(() => {
|
|
54
58
|
PushNotification.configure({
|
|
59
|
+
onAction: function (data: any) {
|
|
60
|
+
console.log(data)
|
|
61
|
+
},
|
|
55
62
|
onNotification: function (data: any) {
|
|
56
63
|
if (data.foreground) {
|
|
57
|
-
|
|
64
|
+
if (notificationMessage) {
|
|
65
|
+
handleNotification(notificationMessage)
|
|
66
|
+
}
|
|
58
67
|
}
|
|
68
|
+
data.finish(PushNotificationIOS.FetchResult.NoData);
|
|
59
69
|
},
|
|
60
70
|
popInitialNotification: true,
|
|
61
71
|
requestPermissions: true
|
|
@@ -77,12 +87,17 @@ export const InngageNotificationMessage = (firebaseListenCallback?: any) => {
|
|
|
77
87
|
const handleMessage = async (remoteMessage: any) => {
|
|
78
88
|
const notificationData = remoteMessage.data;
|
|
79
89
|
|
|
90
|
+
if (notificationData.additional_data != null)
|
|
91
|
+
await AsyncStorage.setItem('inapp', notificationData.additional_data);
|
|
92
|
+
|
|
80
93
|
if (InngageProperties.getDebugMode())
|
|
81
94
|
console.log('Remote message received in foreground: ', remoteMessage);
|
|
82
95
|
|
|
83
96
|
if (firebaseListenCallback != null && remoteMessage != null)
|
|
84
97
|
firebaseListenCallback(notificationData)
|
|
85
98
|
|
|
99
|
+
setNotificationMessage(remoteMessage);
|
|
100
|
+
|
|
86
101
|
PushNotification.localNotification({
|
|
87
102
|
autoCancel: true,
|
|
88
103
|
bigPictureUrl: remoteMessage.notification?.android?.imageUrl,
|
|
@@ -92,10 +107,6 @@ export const InngageNotificationMessage = (firebaseListenCallback?: any) => {
|
|
|
92
107
|
vibration: 300,
|
|
93
108
|
channelId: "channel_id",
|
|
94
109
|
});
|
|
95
|
-
|
|
96
|
-
if (notificationData.additional_data != null)
|
|
97
|
-
await AsyncStorage.setItem('inapp', notificationData.additional_data);
|
|
98
|
-
|
|
99
110
|
};
|
|
100
111
|
|
|
101
112
|
return messaging().onMessage(handleMessage);
|
|
@@ -141,6 +152,31 @@ export const InngageNotificationMessage = (firebaseListenCallback?: any) => {
|
|
|
141
152
|
app_token: InngageProperties.appToken,
|
|
142
153
|
}
|
|
143
154
|
};
|
|
155
|
+
|
|
156
|
+
if (remoteMessage.data?.url) {
|
|
157
|
+
if (remoteMessage.data?.type === 'inapp') {
|
|
158
|
+
try {
|
|
159
|
+
if (await InAppBrowser.isAvailable()) {
|
|
160
|
+
await InAppBrowser.open(remoteMessage.data?.url, {
|
|
161
|
+
dismissButtonStyle: 'close',
|
|
162
|
+
preferredBarTintColor: '#453AA4',
|
|
163
|
+
preferredControlTintColor: 'white',
|
|
164
|
+
enableDefaultShare: true,
|
|
165
|
+
enableBarCollapsing: true,
|
|
166
|
+
});
|
|
167
|
+
} else {
|
|
168
|
+
Linking.openURL(remoteMessage.data?.url);
|
|
169
|
+
}
|
|
170
|
+
} catch (error) {
|
|
171
|
+
console.error(error);
|
|
172
|
+
}
|
|
173
|
+
} else if (remoteMessage.data?.type === 'deep') {
|
|
174
|
+
Linking.openURL(remoteMessage.data?.url).catch((err) =>
|
|
175
|
+
console.error('Erro ao abrir o link:', err)
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
144
180
|
await ApiService.sendNotification(request);
|
|
145
181
|
}
|
|
146
182
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { InApp } from './components/in_app';
|
|
2
|
+
import { useInAppHandler, messagingHeadlessTask } from './firebase/notifications_listener'
|
|
2
3
|
import Inngage from './Inngage';
|
|
3
4
|
|
|
4
|
-
//-------------- In-APP Component -------------//
|
|
5
5
|
export { InApp };
|
|
6
|
-
|
|
7
|
-
//-------------- Inngage Wrapper --------------//
|
|
6
|
+
export { useInAppHandler, messagingHeadlessTask }
|
|
8
7
|
export default Inngage;
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|