@inngageregistry/inngage-react 4.0.0-alpha.2 → 4.0.0-alpha.3
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 +1 -1
- package/src/Inngage.ts +4 -13
- package/src/components/in_app.tsx +75 -19
- package/src/components/styles.ts +58 -85
- package/src/firebase/notifications_listener.ts +13 -16
- package/src/index.ts +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inngageregistry/inngage-react",
|
|
3
|
-
"version": "4.0.0-alpha.
|
|
3
|
+
"version": "4.0.0-alpha.3",
|
|
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",
|
package/src/Inngage.ts
CHANGED
|
@@ -11,12 +11,6 @@ import RNPermissions, { NotificationOption, RESULTS } from 'react-native-permiss
|
|
|
11
11
|
|
|
12
12
|
import ApiService from './services/api_service';
|
|
13
13
|
|
|
14
|
-
import {
|
|
15
|
-
SUBSCRIBE_REQUEST,
|
|
16
|
-
EVENT_REQUEST,
|
|
17
|
-
USER_DATA_REQUEST,
|
|
18
|
-
} from './models/requests';
|
|
19
|
-
|
|
20
14
|
const API_LEVEL_33 = 33;
|
|
21
15
|
|
|
22
16
|
// --- Get Firebase Access ------/
|
|
@@ -73,10 +67,7 @@ interface SubscriptionProps {
|
|
|
73
67
|
}
|
|
74
68
|
|
|
75
69
|
interface SendEventProps {
|
|
76
|
-
appToken: string,
|
|
77
70
|
eventName: string,
|
|
78
|
-
identifier?: string,
|
|
79
|
-
registration?: string,
|
|
80
71
|
conversionEvent?: boolean,
|
|
81
72
|
conversionValue?: number,
|
|
82
73
|
conversionNotId?: string,
|
|
@@ -156,9 +147,9 @@ class Inngage {
|
|
|
156
147
|
|
|
157
148
|
static async sendEvent({
|
|
158
149
|
eventName,
|
|
159
|
-
conversionEvent,
|
|
160
|
-
conversionValue,
|
|
161
|
-
conversionNotId,
|
|
150
|
+
conversionEvent = false,
|
|
151
|
+
conversionValue = 0,
|
|
152
|
+
conversionNotId = "",
|
|
162
153
|
eventValues,
|
|
163
154
|
}: SendEventProps) {
|
|
164
155
|
const inngage = Inngage.getInstance();
|
|
@@ -171,7 +162,7 @@ class Inngage {
|
|
|
171
162
|
identifier: InngageProperties.identifier,
|
|
172
163
|
registration,
|
|
173
164
|
eventName,
|
|
174
|
-
conversionEvent
|
|
165
|
+
conversionEvent,
|
|
175
166
|
conversionValue,
|
|
176
167
|
conversionNotId,
|
|
177
168
|
eventValues,
|
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import {
|
|
3
|
+
StyleSheet,
|
|
4
|
+
Image,
|
|
3
5
|
View,
|
|
4
6
|
Text,
|
|
5
7
|
TouchableOpacity,
|
|
6
8
|
ImageBackground,
|
|
9
|
+
Dimensions,
|
|
7
10
|
} from "react-native";
|
|
8
11
|
|
|
9
12
|
import AsyncStorage from "@react-native-async-storage/async-storage";
|
|
13
|
+
import Carousel from 'react-native-snap-carousel';
|
|
10
14
|
|
|
11
15
|
import { buildStyles } from "./styles";
|
|
12
16
|
import { Modal } from "../components/modal";
|
|
17
|
+
import { InngageProperties } from "../models/inngage_properties";
|
|
13
18
|
|
|
14
19
|
interface InAppData {
|
|
15
20
|
inapp_message: boolean
|
|
@@ -23,32 +28,54 @@ interface InAppData {
|
|
|
23
28
|
btn_right_txt_color: string
|
|
24
29
|
btn_right_bg_color: string
|
|
25
30
|
background_image: string
|
|
26
|
-
|
|
31
|
+
btn_left_txt: string
|
|
27
32
|
btn_left_action_type: string
|
|
28
33
|
btn_left_action_link: string
|
|
29
|
-
|
|
34
|
+
btn_right_txt: string
|
|
30
35
|
btn_right_action_type: string
|
|
31
36
|
btn_right_action_link: string
|
|
32
|
-
|
|
37
|
+
rich_content: string
|
|
33
38
|
inpression: string
|
|
34
39
|
bg_img_action_type: string
|
|
35
40
|
bg_img_action_link: string
|
|
36
41
|
dot_color: string
|
|
37
42
|
}
|
|
38
43
|
|
|
39
|
-
|
|
44
|
+
interface InAppRichContent {
|
|
45
|
+
carousel: boolean
|
|
46
|
+
img1: string
|
|
47
|
+
img2: string
|
|
48
|
+
img3: string
|
|
49
|
+
img4: string
|
|
50
|
+
img5: string
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
interface InAppProps {
|
|
54
|
+
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function InApp(props: InAppProps): JSX.Element {
|
|
58
|
+
const { width: screenWidth } = Dimensions.get('window');
|
|
59
|
+
|
|
60
|
+
const sliderWidth = screenWidth;
|
|
61
|
+
const itemWidth = screenWidth * 0.9;
|
|
62
|
+
|
|
40
63
|
const [data, setData] = React.useState<InAppData>();
|
|
64
|
+
const [richContent, setRichContent] = React.useState<InAppRichContent>();
|
|
41
65
|
const [visible, setVisible] = React.useState(false);
|
|
42
66
|
|
|
43
67
|
React.useEffect(() => {
|
|
44
68
|
const fetchAdditionalData = async () => {
|
|
45
69
|
try {
|
|
70
|
+
console.log('in app message')
|
|
46
71
|
const data = await AsyncStorage.getItem('inapp');
|
|
47
72
|
if (data) {
|
|
48
73
|
const parsedData = JSON.parse(data);
|
|
74
|
+
const richContentData = parsedData.rich_content;
|
|
49
75
|
|
|
50
76
|
setVisible(true);
|
|
51
77
|
setData(parsedData);
|
|
78
|
+
setRichContent(richContentData);
|
|
52
79
|
}
|
|
53
80
|
} catch (error) {
|
|
54
81
|
console.error('Error retrieving additionalData from AsyncStorage:', error);
|
|
@@ -58,15 +85,43 @@ export function InAppContainer(): JSX.Element {
|
|
|
58
85
|
fetchAdditionalData();
|
|
59
86
|
}, []);
|
|
60
87
|
|
|
61
|
-
const styles = buildStyles(data);
|
|
88
|
+
const styles = buildStyles(data, screenWidth * 0.9);
|
|
62
89
|
|
|
63
90
|
const handleDismissInApp = async () => {
|
|
64
91
|
await AsyncStorage.removeItem('inapp');
|
|
65
92
|
setVisible(false);
|
|
66
93
|
}
|
|
67
94
|
|
|
68
|
-
|
|
69
|
-
|
|
95
|
+
const imageUrls: string[] = [
|
|
96
|
+
richContent?.img1 ?? '',
|
|
97
|
+
richContent?.img2 ?? '',
|
|
98
|
+
richContent?.img3 ?? '',
|
|
99
|
+
richContent?.img4 ?? '',
|
|
100
|
+
richContent?.img5 ?? ''
|
|
101
|
+
];
|
|
102
|
+
|
|
103
|
+
const stylesCarousel = StyleSheet.create({
|
|
104
|
+
itemContainer: {
|
|
105
|
+
justifyContent: 'center',
|
|
106
|
+
height: 250
|
|
107
|
+
},
|
|
108
|
+
itemImg: {
|
|
109
|
+
height: 250,
|
|
110
|
+
},
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
const _renderItem = ({ item, index }) => {
|
|
114
|
+
return (
|
|
115
|
+
<View style={stylesCarousel.itemContainer}>
|
|
116
|
+
<Image style={[props, stylesCarousel.itemImg]} source={{ uri: item }} />
|
|
117
|
+
</View>
|
|
118
|
+
)
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (InngageProperties.getDebugMode() && data != null) {
|
|
122
|
+
console.log('INNGAGE - Data In App:', data)
|
|
123
|
+
console.log('INNGAGE - Data Rich Content:', richContent)
|
|
124
|
+
}
|
|
70
125
|
|
|
71
126
|
return (
|
|
72
127
|
<Modal
|
|
@@ -74,6 +129,12 @@ export function InAppContainer(): JSX.Element {
|
|
|
74
129
|
transparent={true}
|
|
75
130
|
visible={visible}>
|
|
76
131
|
<ImageBackground style={styles.content} source={{ uri: data?.background_image }}>
|
|
132
|
+
{richContent?.carousel ? <Carousel
|
|
133
|
+
layout={"default"}
|
|
134
|
+
data={imageUrls}
|
|
135
|
+
sliderWidth={sliderWidth}
|
|
136
|
+
itemWidth={itemWidth}
|
|
137
|
+
renderItem={_renderItem} /> : null}
|
|
77
138
|
<TouchableOpacity style={styles.closeButton} onPress={handleDismissInApp}>
|
|
78
139
|
<Text>X</Text>
|
|
79
140
|
</TouchableOpacity>
|
|
@@ -82,21 +143,16 @@ export function InAppContainer(): JSX.Element {
|
|
|
82
143
|
<Text style={styles.body}>{data?.body}</Text>
|
|
83
144
|
</View>
|
|
84
145
|
<View style={styles.footer}>
|
|
85
|
-
<TouchableOpacity
|
|
146
|
+
{data?.btn_left_txt != null ? <TouchableOpacity
|
|
86
147
|
style={styles.buttonLeft}>
|
|
87
|
-
<Text style={styles.textButton}>{data?.
|
|
88
|
-
</TouchableOpacity>
|
|
89
|
-
<TouchableOpacity
|
|
148
|
+
<Text style={styles.textButton}>{data?.btn_left_txt}</Text>
|
|
149
|
+
</TouchableOpacity> : null}
|
|
150
|
+
{data?.btn_right_txt != null ? <TouchableOpacity
|
|
90
151
|
style={styles.buttonRight}>
|
|
91
|
-
<Text style={styles.textButton}>{data?.
|
|
92
|
-
</TouchableOpacity>
|
|
152
|
+
<Text style={styles.textButton}>{data?.btn_right_txt}</Text>
|
|
153
|
+
</TouchableOpacity> : null}
|
|
93
154
|
</View>
|
|
94
155
|
</ImageBackground>
|
|
95
156
|
</Modal>
|
|
96
157
|
)
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
158
|
+
}
|
package/src/components/styles.ts
CHANGED
|
@@ -1,97 +1,70 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { PlatformColor, StyleSheet } from "react-native";
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
export const buildStyles = (data: any) => StyleSheet.create({
|
|
4
|
+
export const buildStyles = (data: any, screen: any) => StyleSheet.create({
|
|
5
5
|
closeButton: {
|
|
6
6
|
position: 'absolute',
|
|
7
7
|
top: 10,
|
|
8
8
|
right: 10,
|
|
9
9
|
zIndex: 10,
|
|
10
10
|
},
|
|
11
|
-
content:
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
25
|
-
messageData: Platform.select({
|
|
26
|
-
android: {
|
|
27
|
-
marginTop: 12
|
|
28
|
-
},
|
|
29
|
-
default: {}
|
|
30
|
-
}),
|
|
11
|
+
content: {
|
|
12
|
+
backgroundColor: data?.background_color,
|
|
13
|
+
flexDirection: "column",
|
|
14
|
+
borderRadius: 3,
|
|
15
|
+
paddingBottom: 16,
|
|
16
|
+
paddingRight: 16,
|
|
17
|
+
paddingLeft: 16,
|
|
18
|
+
margin: 16,
|
|
19
|
+
overflow: "hidden",
|
|
20
|
+
elevation: 10,
|
|
21
|
+
width: screen,
|
|
22
|
+
alignItems: "center"
|
|
23
|
+
},
|
|
24
|
+
messageData: { marginTop: 12 },
|
|
31
25
|
footer: {
|
|
32
26
|
flexDirection: "row",
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
27
|
+
alignItems: "center",
|
|
28
|
+
justifyContent: "flex-end",
|
|
29
|
+
marginTop: 4,
|
|
30
|
+
},
|
|
31
|
+
title: {
|
|
32
|
+
color: PlatformColor(
|
|
33
|
+
`@android:color/${"primary_text_light"}`
|
|
34
|
+
),
|
|
35
|
+
fontWeight: "500",
|
|
36
|
+
fontSize: 18,
|
|
37
|
+
},
|
|
38
|
+
body: {
|
|
39
|
+
color: PlatformColor(
|
|
40
|
+
`@android:color/${"secondary_text_light"}`
|
|
41
|
+
),
|
|
42
|
+
fontSize: 16,
|
|
43
|
+
marginTop: 10,
|
|
44
|
+
marginBottom: 10,
|
|
45
|
+
},
|
|
46
|
+
buttonLeft: {
|
|
47
|
+
margin: 2,
|
|
48
|
+
flex: 1,
|
|
49
|
+
backgroundColor: data?.btn_left_bg_color,
|
|
50
|
+
justifyContent: "center",
|
|
51
|
+
alignItems: "center",
|
|
52
|
+
},
|
|
53
|
+
buttonRight: {
|
|
54
|
+
margin: 2,
|
|
55
|
+
flex: 1,
|
|
56
|
+
backgroundColor: data?.btn_right_bg_color,
|
|
57
|
+
justifyContent: "center",
|
|
58
|
+
alignItems: "center",
|
|
59
|
+
},
|
|
60
|
+
textButton: {
|
|
61
|
+
color: PlatformColor(
|
|
62
|
+
`@android:color/${"secondary_text_light"}`
|
|
63
|
+
),
|
|
64
|
+
textAlign: "center",
|
|
65
|
+
backgroundColor: "transparent",
|
|
66
|
+
padding: 8,
|
|
67
|
+
fontSize: 14,
|
|
68
|
+
textTransform: "uppercase",
|
|
41
69
|
},
|
|
42
|
-
title: Platform.select({
|
|
43
|
-
android: {
|
|
44
|
-
color: PlatformColor(
|
|
45
|
-
`@android:color/${"primary_text_light"}`
|
|
46
|
-
),
|
|
47
|
-
fontWeight: "500",
|
|
48
|
-
fontSize: 18,
|
|
49
|
-
},
|
|
50
|
-
|
|
51
|
-
default: {},
|
|
52
|
-
}),
|
|
53
|
-
body: Platform.select({
|
|
54
|
-
android: {
|
|
55
|
-
color: PlatformColor(
|
|
56
|
-
`@android:color/${"secondary_text_light"}`
|
|
57
|
-
),
|
|
58
|
-
fontSize: 16,
|
|
59
|
-
marginTop: 10,
|
|
60
|
-
marginBottom: 10,
|
|
61
|
-
},
|
|
62
|
-
default: {},
|
|
63
|
-
}),
|
|
64
|
-
buttonLeft: Platform.select({
|
|
65
|
-
android: {
|
|
66
|
-
margin: 2,
|
|
67
|
-
flex: 1,
|
|
68
|
-
backgroundColor: data?.btn_left_bg_color,
|
|
69
|
-
justifyContent: "center",
|
|
70
|
-
alignItems: "center",
|
|
71
|
-
},
|
|
72
|
-
default: {},
|
|
73
|
-
}),
|
|
74
|
-
buttonRight: Platform.select({
|
|
75
|
-
android: {
|
|
76
|
-
margin: 2,
|
|
77
|
-
flex: 1,
|
|
78
|
-
backgroundColor: data?.btn_right_bg_color,
|
|
79
|
-
justifyContent: "center",
|
|
80
|
-
alignItems: "center",
|
|
81
|
-
},
|
|
82
|
-
default: {},
|
|
83
|
-
}),
|
|
84
|
-
textButton: Platform.select({
|
|
85
|
-
android: {
|
|
86
|
-
color: PlatformColor(
|
|
87
|
-
`@android:color/${"secondary_text_light"}`
|
|
88
|
-
),
|
|
89
|
-
textAlign: "center",
|
|
90
|
-
backgroundColor: "transparent",
|
|
91
|
-
padding: 8,
|
|
92
|
-
fontSize: 14,
|
|
93
|
-
textTransform: "uppercase",
|
|
94
|
-
},
|
|
95
|
-
default: {},
|
|
96
|
-
}),
|
|
97
70
|
})
|
|
@@ -8,6 +8,15 @@ import PushNotification, { Importance } from 'react-native-push-notification'
|
|
|
8
8
|
import { InngageProperties } from '../models/inngage_properties';
|
|
9
9
|
import * as ApiService from '../services/api_service'
|
|
10
10
|
|
|
11
|
+
export const messagingHeadlessTask = () => {
|
|
12
|
+
return messaging().setBackgroundMessageHandler(async remoteMessage => {
|
|
13
|
+
if (InngageProperties.getDebugMode())
|
|
14
|
+
console.log('INNGAGE - Data in background and closed app: ', remoteMessage)
|
|
15
|
+
if (remoteMessage?.data?.additional_data != null)
|
|
16
|
+
await AsyncStorage.setItem('inapp', remoteMessage?.data?.additional_data);
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
|
|
11
20
|
export const InngageNotificationMessage = (firebaseListenCallback?: any) => {
|
|
12
21
|
useEffect(() => {
|
|
13
22
|
PushNotification.configure({
|
|
@@ -61,24 +70,12 @@ export const InngageNotificationMessage = (firebaseListenCallback?: any) => {
|
|
|
61
70
|
}, []);
|
|
62
71
|
|
|
63
72
|
useEffect(() => {
|
|
64
|
-
|
|
65
|
-
const notificationData = remoteMessage.data;
|
|
66
|
-
|
|
67
|
-
if (InngageProperties.getDebugMode())
|
|
68
|
-
console.log('Remote message received in background: ', remoteMessage);
|
|
69
|
-
|
|
73
|
+
messaging().onNotificationOpenedApp(remoteMessage => {
|
|
70
74
|
if (remoteMessage != null)
|
|
71
75
|
firebaseListenCallback(remoteMessage.data)
|
|
72
76
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
messaging().onNotificationOpenedApp(remoteMessage => {
|
|
77
|
-
handleNotification(remoteMessage)
|
|
78
|
-
})
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
return messaging().setBackgroundMessageHandler(backgroundHandler);
|
|
77
|
+
handleNotification(remoteMessage)
|
|
78
|
+
})
|
|
82
79
|
}, []);
|
|
83
80
|
|
|
84
81
|
useEffect(() => {
|
|
@@ -100,7 +97,7 @@ export const InngageNotificationMessage = (firebaseListenCallback?: any) => {
|
|
|
100
97
|
handleNotification(remoteMessage)
|
|
101
98
|
}
|
|
102
99
|
} catch (e) {
|
|
103
|
-
console.
|
|
100
|
+
console.error(e);
|
|
104
101
|
}
|
|
105
102
|
};
|
|
106
103
|
|
package/src/index.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { InApp } from './components/in_app';
|
|
2
2
|
import Inngage from './Inngage';
|
|
3
3
|
|
|
4
4
|
//-------------- In-APP Component -------------//
|
|
5
|
-
export {
|
|
5
|
+
export { InApp };
|
|
6
6
|
|
|
7
7
|
//-------------- Inngage Wrapper --------------//
|
|
8
8
|
export default Inngage;
|