@inngageregistry/inngage-react 4.0.0-beta.2 → 4.0.1
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 +60 -60
- package/dist/Inngage.d.ts +28 -0
- package/dist/Inngage.js +161 -0
- package/dist/api/api.d.ts +4 -0
- package/{src/api/api.ts → dist/api/api.js} +22 -28
- package/dist/api/handler.d.ts +1 -0
- package/dist/api/handler.js +44 -0
- package/dist/components/in_app.d.ts +6 -0
- package/dist/components/in_app.js +92 -0
- package/dist/components/modal.d.ts +26 -0
- package/dist/components/modal.js +158 -0
- package/dist/components/styles.d.ts +88 -0
- package/dist/components/styles.js +86 -0
- package/dist/firebase/notifications_config.d.ts +3 -0
- package/dist/firebase/notifications_config.js +30 -0
- package/dist/firebase/notifications_listener.d.ts +8 -0
- package/dist/firebase/notifications_listener.js +202 -0
- package/{src/index.ts → dist/index.d.ts} +6 -11
- package/dist/index.js +6 -0
- package/dist/models/inngage_properties.d.ts +11 -0
- package/dist/models/inngage_properties.js +13 -0
- package/dist/models/requests.d.ts +40 -0
- package/{src/models/requests.ts → dist/models/requests.js} +40 -42
- package/dist/services/api_services.d.ts +7 -0
- package/{src/services/api_services.ts → dist/services/api_services.js} +25 -30
- package/dist/services/handler.d.ts +1 -0
- package/dist/services/handler.js +38 -0
- package/dist/services/inngage.d.ts +4 -0
- package/dist/services/inngage.js +22 -0
- package/dist/utils.d.ts +5 -0
- package/dist/utils.js +26 -0
- package/package.json +79 -40
- package/.editorconfig +0 -6
- package/src/Inngage.ts +0 -193
- package/src/api/handler.ts +0 -53
- package/src/components/in_app.tsx +0 -192
- package/src/components/modal.tsx +0 -221
- package/src/components/styles.ts +0 -88
- package/src/firebase/notifications_listener.ts +0 -182
- package/src/models/inngage_properties.ts +0 -13
- package/src/services/handler.ts +0 -41
- package/src/services/inngage.ts +0 -23
- package/src/utils.ts +0 -35
- package/tsconfig.json +0 -27
|
@@ -1,192 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import {
|
|
3
|
-
StyleSheet,
|
|
4
|
-
Image,
|
|
5
|
-
View,
|
|
6
|
-
Text,
|
|
7
|
-
TouchableOpacity,
|
|
8
|
-
ImageBackground,
|
|
9
|
-
Dimensions,
|
|
10
|
-
Linking,
|
|
11
|
-
} from "react-native";
|
|
12
|
-
|
|
13
|
-
import AsyncStorage from "@react-native-async-storage/async-storage";
|
|
14
|
-
import Carousel from 'react-native-snap-carousel';
|
|
15
|
-
|
|
16
|
-
import { buildStyles } from "./styles";
|
|
17
|
-
import { Modal } from "../components/modal";
|
|
18
|
-
import { InngageProperties } from "../models/inngage_properties";
|
|
19
|
-
|
|
20
|
-
import InAppBrowser from 'react-native-inappbrowser-reborn';
|
|
21
|
-
|
|
22
|
-
interface InAppData {
|
|
23
|
-
inapp_message: boolean
|
|
24
|
-
title: string
|
|
25
|
-
body: string
|
|
26
|
-
title_font_color: string
|
|
27
|
-
body_font_color: string
|
|
28
|
-
background_color: string
|
|
29
|
-
btn_left_txt_color: string
|
|
30
|
-
btn_left_bg_color: string
|
|
31
|
-
btn_right_txt_color: string
|
|
32
|
-
btn_right_bg_color: string
|
|
33
|
-
background_image: string
|
|
34
|
-
btn_left_txt: string
|
|
35
|
-
btn_left_action_type: string
|
|
36
|
-
btn_left_action_link: string
|
|
37
|
-
btn_right_txt: string
|
|
38
|
-
btn_right_action_type: string
|
|
39
|
-
btn_right_action_link: string
|
|
40
|
-
rich_content: string
|
|
41
|
-
inpression: string
|
|
42
|
-
bg_img_action_type: string
|
|
43
|
-
bg_img_action_link: string
|
|
44
|
-
dot_color: string
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
interface InAppRichContent {
|
|
48
|
-
carousel: boolean
|
|
49
|
-
img1: string
|
|
50
|
-
img2: string
|
|
51
|
-
img3: string
|
|
52
|
-
img4: string
|
|
53
|
-
img5: string
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
interface InAppProps {
|
|
57
|
-
onDismiss: () => void;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export function InApp({ onDismiss }: InAppProps): JSX.Element {
|
|
61
|
-
const { width: screenWidth } = Dimensions.get('window');
|
|
62
|
-
|
|
63
|
-
const sliderWidth = screenWidth;
|
|
64
|
-
const itemWidth = screenWidth * 0.9;
|
|
65
|
-
|
|
66
|
-
const [data, setData] = React.useState<InAppData>();
|
|
67
|
-
const [richContent, setRichContent] = React.useState<InAppRichContent>();
|
|
68
|
-
const [visible, setVisible] = React.useState(false);
|
|
69
|
-
|
|
70
|
-
React.useEffect(() => {
|
|
71
|
-
const fetchAdditionalData = async () => {
|
|
72
|
-
try {
|
|
73
|
-
console.log('in app message')
|
|
74
|
-
const data = await AsyncStorage.getItem('inapp');
|
|
75
|
-
console.log(data)
|
|
76
|
-
if (data) {
|
|
77
|
-
const parsedData = JSON.parse(data);
|
|
78
|
-
const richContentData = parsedData.rich_content;
|
|
79
|
-
|
|
80
|
-
setVisible(true);
|
|
81
|
-
setData(parsedData);
|
|
82
|
-
setRichContent(richContentData);
|
|
83
|
-
}
|
|
84
|
-
} catch (error) {
|
|
85
|
-
console.error('Error retrieving additionalData from AsyncStorage:', error);
|
|
86
|
-
}
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
fetchAdditionalData();
|
|
90
|
-
}, []);
|
|
91
|
-
|
|
92
|
-
const styles = buildStyles(data, screenWidth * 0.9);
|
|
93
|
-
|
|
94
|
-
const handleDismissInApp = async () => {
|
|
95
|
-
await AsyncStorage.removeItem('inapp');
|
|
96
|
-
setVisible(false);
|
|
97
|
-
onDismiss();
|
|
98
|
-
}
|
|
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
|
-
|
|
124
|
-
const imageUrls: string[] = [
|
|
125
|
-
richContent?.img1 ?? '',
|
|
126
|
-
richContent?.img2 ?? '',
|
|
127
|
-
richContent?.img3 ?? '',
|
|
128
|
-
richContent?.img4 ?? '',
|
|
129
|
-
richContent?.img5 ?? ''
|
|
130
|
-
];
|
|
131
|
-
|
|
132
|
-
const stylesCarousel = StyleSheet.create({
|
|
133
|
-
itemContainer: {
|
|
134
|
-
justifyContent: 'center',
|
|
135
|
-
height: 250
|
|
136
|
-
},
|
|
137
|
-
itemImg: {
|
|
138
|
-
height: 250,
|
|
139
|
-
},
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
const _renderItem = ({ item, index }) => {
|
|
143
|
-
return (
|
|
144
|
-
<View style={stylesCarousel.itemContainer}>
|
|
145
|
-
<Image style={[stylesCarousel.itemImg]} source={{ uri: item }} />
|
|
146
|
-
</View>
|
|
147
|
-
)
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
if (InngageProperties.getDebugMode() && data != null) {
|
|
151
|
-
console.log('INNGAGE - Data In App:', data)
|
|
152
|
-
console.log('INNGAGE - Data Rich Content:', richContent)
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
return (
|
|
156
|
-
<Modal
|
|
157
|
-
onBackdropPress={handleDismissInApp}
|
|
158
|
-
renderToHardwareTextureAndroid={true}
|
|
159
|
-
transparent={true}
|
|
160
|
-
visible={visible}>
|
|
161
|
-
<ImageBackground style={styles.content} source={{ uri: data?.background_image }}>
|
|
162
|
-
{richContent?.carousel ? <Carousel
|
|
163
|
-
layout={"default"}
|
|
164
|
-
data={imageUrls}
|
|
165
|
-
sliderWidth={sliderWidth}
|
|
166
|
-
itemWidth={itemWidth}
|
|
167
|
-
renderItem={_renderItem} /> : null}
|
|
168
|
-
<TouchableOpacity style={styles.closeButton} onPress={handleDismissInApp}>
|
|
169
|
-
<Text style={styles.textButton}>X</Text>
|
|
170
|
-
</TouchableOpacity>
|
|
171
|
-
<View style={styles.messageData}>
|
|
172
|
-
<Text style={styles.title}>{data?.title}</Text>
|
|
173
|
-
<Text style={styles.body}>{data?.body}</Text>
|
|
174
|
-
</View>
|
|
175
|
-
<View style={styles.footer}>
|
|
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}
|
|
188
|
-
</View>
|
|
189
|
-
</ImageBackground>
|
|
190
|
-
</Modal>
|
|
191
|
-
)
|
|
192
|
-
}
|
package/src/components/modal.tsx
DELETED
|
@@ -1,221 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import {
|
|
3
|
-
Animated, Easing,
|
|
4
|
-
Modal as ReactNativeModal,
|
|
5
|
-
ModalProps as ReactNativeModalProps,
|
|
6
|
-
Platform,
|
|
7
|
-
StyleProp,
|
|
8
|
-
StyleSheet,
|
|
9
|
-
TouchableWithoutFeedback,
|
|
10
|
-
ViewStyle
|
|
11
|
-
} from "react-native";
|
|
12
|
-
import { Component } from "react";
|
|
13
|
-
|
|
14
|
-
const MODAL_ANIM_DURATION = 300;
|
|
15
|
-
const MODAL_BACKDROP_OPACITY = 0.3;
|
|
16
|
-
|
|
17
|
-
const CONTENT_ANIMATION_IN = Platform.select({
|
|
18
|
-
ios: {
|
|
19
|
-
opacity: {
|
|
20
|
-
inputRange: [0, 1],
|
|
21
|
-
outputRange: [0, 1],
|
|
22
|
-
},
|
|
23
|
-
scale: {
|
|
24
|
-
inputRange: [0, 0.5, 1],
|
|
25
|
-
outputRange: [1.2, 1.1, 1],
|
|
26
|
-
},
|
|
27
|
-
},
|
|
28
|
-
android: {
|
|
29
|
-
opacity: {
|
|
30
|
-
inputRange: [0, 0.5, 1],
|
|
31
|
-
outputRange: [0, 1, 1],
|
|
32
|
-
},
|
|
33
|
-
scale: {
|
|
34
|
-
inputRange: [0, 1],
|
|
35
|
-
outputRange: [0.3, 1],
|
|
36
|
-
},
|
|
37
|
-
},
|
|
38
|
-
default: {
|
|
39
|
-
opacity: {
|
|
40
|
-
inputRange: [0, 0.5, 1],
|
|
41
|
-
outputRange: [0, 1, 1],
|
|
42
|
-
},
|
|
43
|
-
scale: {
|
|
44
|
-
inputRange: [0, 1],
|
|
45
|
-
outputRange: [0.3, 1],
|
|
46
|
-
},
|
|
47
|
-
},
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
const CONTENT_ANIMATION_OUT = Platform.select({
|
|
51
|
-
default: {
|
|
52
|
-
opacity: {
|
|
53
|
-
inputRange: [0, 1],
|
|
54
|
-
outputRange: [0, 1],
|
|
55
|
-
},
|
|
56
|
-
},
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
export interface ModalProps extends ReactNativeModalProps {
|
|
60
|
-
onBackdropPress?: () => void;
|
|
61
|
-
onHide?: () => void;
|
|
62
|
-
visible?: boolean;
|
|
63
|
-
contentStyle?: StyleProp<ViewStyle>;
|
|
64
|
-
useNativeDriver?: boolean;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
interface ModalState {
|
|
68
|
-
visible: boolean;
|
|
69
|
-
currentAnimation: "none" | "in" | "out";
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
export class Modal extends Component<ModalProps, ModalState> {
|
|
73
|
-
static defaultProps: Partial<ModalProps> = {
|
|
74
|
-
onBackdropPress: () => null,
|
|
75
|
-
onHide: () => null,
|
|
76
|
-
visible: false,
|
|
77
|
-
useNativeDriver: false,
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
state: ModalState = {
|
|
81
|
-
visible: Boolean(this.props.visible),
|
|
82
|
-
currentAnimation: "none",
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
animVal = new Animated.Value(0);
|
|
86
|
-
_isMounted = false;
|
|
87
|
-
|
|
88
|
-
componentDidMount() {
|
|
89
|
-
this._isMounted = true;
|
|
90
|
-
if (this.state.visible) {
|
|
91
|
-
this.show();
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
componentWillUnmount() {
|
|
96
|
-
this._isMounted = false;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
componentDidUpdate(prevProps: ModalProps) {
|
|
100
|
-
if (this.props.visible && !prevProps.visible) {
|
|
101
|
-
this.show();
|
|
102
|
-
} else if (!this.props.visible && prevProps.visible) {
|
|
103
|
-
this.hide();
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
show = () => {
|
|
108
|
-
this.setState({ visible: true, currentAnimation: "in" }, () => {
|
|
109
|
-
Animated.timing(this.animVal, {
|
|
110
|
-
easing: Easing.inOut(Easing.quad),
|
|
111
|
-
useNativeDriver: Boolean(this.props.useNativeDriver),
|
|
112
|
-
duration: MODAL_ANIM_DURATION,
|
|
113
|
-
toValue: 1,
|
|
114
|
-
}).start(() => {
|
|
115
|
-
this.setState({ currentAnimation: "none" });
|
|
116
|
-
});
|
|
117
|
-
});
|
|
118
|
-
};
|
|
119
|
-
|
|
120
|
-
hide = () => {
|
|
121
|
-
this.setState({ currentAnimation: "out" }, () => {
|
|
122
|
-
Animated.timing(this.animVal, {
|
|
123
|
-
easing: Easing.inOut(Easing.quad),
|
|
124
|
-
useNativeDriver: Boolean(this.props.useNativeDriver),
|
|
125
|
-
duration: MODAL_ANIM_DURATION,
|
|
126
|
-
toValue: 0,
|
|
127
|
-
}).start(() => {
|
|
128
|
-
if (this._isMounted) {
|
|
129
|
-
this.setState({ currentAnimation: "none" });
|
|
130
|
-
this.setState({ visible: false }, this.props.onHide);
|
|
131
|
-
}
|
|
132
|
-
});
|
|
133
|
-
});
|
|
134
|
-
};
|
|
135
|
-
|
|
136
|
-
render() {
|
|
137
|
-
const {
|
|
138
|
-
children,
|
|
139
|
-
onBackdropPress,
|
|
140
|
-
contentStyle,
|
|
141
|
-
...otherProps
|
|
142
|
-
} = this.props;
|
|
143
|
-
const { currentAnimation, visible } = this.state;
|
|
144
|
-
|
|
145
|
-
const backdropAnimatedStyle = {
|
|
146
|
-
opacity: this.animVal.interpolate({
|
|
147
|
-
inputRange: [0, 1],
|
|
148
|
-
outputRange: [0, MODAL_BACKDROP_OPACITY],
|
|
149
|
-
}),
|
|
150
|
-
};
|
|
151
|
-
|
|
152
|
-
const contentAnimatedStyle =
|
|
153
|
-
currentAnimation === "in"
|
|
154
|
-
? {
|
|
155
|
-
opacity: this.animVal.interpolate({
|
|
156
|
-
inputRange: CONTENT_ANIMATION_IN.opacity.inputRange,
|
|
157
|
-
outputRange: CONTENT_ANIMATION_IN.opacity.outputRange,
|
|
158
|
-
extrapolate: "clamp",
|
|
159
|
-
}),
|
|
160
|
-
transform: [
|
|
161
|
-
{
|
|
162
|
-
scale: this.animVal.interpolate({
|
|
163
|
-
inputRange: CONTENT_ANIMATION_IN.scale.inputRange,
|
|
164
|
-
outputRange: CONTENT_ANIMATION_IN.scale.outputRange,
|
|
165
|
-
extrapolate: "clamp",
|
|
166
|
-
}),
|
|
167
|
-
},
|
|
168
|
-
],
|
|
169
|
-
}
|
|
170
|
-
: {
|
|
171
|
-
opacity: this.animVal.interpolate({
|
|
172
|
-
inputRange: CONTENT_ANIMATION_OUT.opacity.inputRange,
|
|
173
|
-
outputRange: CONTENT_ANIMATION_OUT.opacity.outputRange,
|
|
174
|
-
extrapolate: "clamp",
|
|
175
|
-
}),
|
|
176
|
-
};
|
|
177
|
-
|
|
178
|
-
return (
|
|
179
|
-
<ReactNativeModal
|
|
180
|
-
transparent
|
|
181
|
-
animationType="none"
|
|
182
|
-
{...otherProps}
|
|
183
|
-
visible={visible}
|
|
184
|
-
>
|
|
185
|
-
<TouchableWithoutFeedback onPress={onBackdropPress}>
|
|
186
|
-
<Animated.View style={[styles.backdrop, backdropAnimatedStyle]} />
|
|
187
|
-
</TouchableWithoutFeedback>
|
|
188
|
-
{visible && (
|
|
189
|
-
<Animated.View
|
|
190
|
-
style={[styles.content, contentAnimatedStyle, contentStyle]}
|
|
191
|
-
pointerEvents="box-none"
|
|
192
|
-
needsOffscreenAlphaCompositing={["in", "out"].includes(
|
|
193
|
-
currentAnimation
|
|
194
|
-
)}
|
|
195
|
-
>
|
|
196
|
-
{children}
|
|
197
|
-
</Animated.View>
|
|
198
|
-
)}
|
|
199
|
-
</ReactNativeModal>
|
|
200
|
-
);
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
const styles = StyleSheet.create({
|
|
205
|
-
backdrop: {
|
|
206
|
-
position: "absolute",
|
|
207
|
-
top: 0,
|
|
208
|
-
bottom: 0,
|
|
209
|
-
left: 0,
|
|
210
|
-
right: 0,
|
|
211
|
-
backgroundColor: "black",
|
|
212
|
-
opacity: 0,
|
|
213
|
-
},
|
|
214
|
-
content: {
|
|
215
|
-
flex: 1,
|
|
216
|
-
alignItems: "center",
|
|
217
|
-
justifyContent: "center",
|
|
218
|
-
},
|
|
219
|
-
});
|
|
220
|
-
|
|
221
|
-
export default Modal;
|
package/src/components/styles.ts
DELETED
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
import { PlatformColor, StyleSheet } from "react-native";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export const buildStyles = (data: any, screen: any) => StyleSheet.create({
|
|
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,
|
|
15
|
-
position: 'absolute',
|
|
16
|
-
top: 10,
|
|
17
|
-
right: 10,
|
|
18
|
-
zIndex: 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
|
-
},
|
|
25
|
-
content: {
|
|
26
|
-
backgroundColor: data?.background_color,
|
|
27
|
-
flexDirection: "column",
|
|
28
|
-
borderRadius: 20,
|
|
29
|
-
paddingBottom: 16,
|
|
30
|
-
paddingRight: 16,
|
|
31
|
-
paddingLeft: 16,
|
|
32
|
-
margin: 16,
|
|
33
|
-
overflow: "hidden",
|
|
34
|
-
elevation: 10,
|
|
35
|
-
width: screen,
|
|
36
|
-
alignItems: "center"
|
|
37
|
-
},
|
|
38
|
-
messageData: {
|
|
39
|
-
marginTop: 12,
|
|
40
|
-
alignItems: "center",
|
|
41
|
-
justifyContent: "center",
|
|
42
|
-
},
|
|
43
|
-
footer: {
|
|
44
|
-
flexDirection: "row",
|
|
45
|
-
alignItems: "center",
|
|
46
|
-
justifyContent: "flex-end",
|
|
47
|
-
marginTop: 4,
|
|
48
|
-
},
|
|
49
|
-
title: {
|
|
50
|
-
color: data?.title_font_color,
|
|
51
|
-
fontWeight: "500",
|
|
52
|
-
fontSize: 18,
|
|
53
|
-
},
|
|
54
|
-
body: {
|
|
55
|
-
color: data?.body_font_color,
|
|
56
|
-
fontSize: 16,
|
|
57
|
-
marginTop: 10,
|
|
58
|
-
marginBottom: 10,
|
|
59
|
-
},
|
|
60
|
-
buttonLeft: {
|
|
61
|
-
margin: 2,
|
|
62
|
-
flex: 1,
|
|
63
|
-
backgroundColor: data?.btn_left_bg_color,
|
|
64
|
-
justifyContent: "center",
|
|
65
|
-
alignItems: "center",
|
|
66
|
-
},
|
|
67
|
-
buttonRight: {
|
|
68
|
-
margin: 2,
|
|
69
|
-
flex: 1,
|
|
70
|
-
backgroundColor: data?.btn_right_bg_color,
|
|
71
|
-
justifyContent: "center",
|
|
72
|
-
alignItems: "center",
|
|
73
|
-
},
|
|
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,
|
|
83
|
-
textAlign: "center",
|
|
84
|
-
backgroundColor: "transparent",
|
|
85
|
-
padding: 8,
|
|
86
|
-
fontSize: 14,
|
|
87
|
-
},
|
|
88
|
-
})
|
|
@@ -1,182 +0,0 @@
|
|
|
1
|
-
import { useEffect, useState } from 'react';
|
|
2
|
-
|
|
3
|
-
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
4
|
-
|
|
5
|
-
import messaging from '@react-native-firebase/messaging';
|
|
6
|
-
import PushNotificationIOS from "@react-native-community/push-notification-ios";
|
|
7
|
-
import PushNotification, { Importance } from 'react-native-push-notification'
|
|
8
|
-
|
|
9
|
-
import { InngageProperties } from '../models/inngage_properties';
|
|
10
|
-
import * as ApiService from '../services/api_services'
|
|
11
|
-
import { AppState, Linking } from 'react-native';
|
|
12
|
-
import InAppBrowser from 'react-native-inappbrowser-reborn';
|
|
13
|
-
|
|
14
|
-
export const messagingHeadlessTask = () => {
|
|
15
|
-
return messaging().setBackgroundMessageHandler(async remoteMessage => {
|
|
16
|
-
if (InngageProperties.getDebugMode())
|
|
17
|
-
console.log('INNGAGE BACKGROUND AND CLOSED DATA: ', remoteMessage)
|
|
18
|
-
|
|
19
|
-
if (remoteMessage?.data?.additional_data != null) {
|
|
20
|
-
await AsyncStorage.setItem('inapp', remoteMessage?.data?.additional_data);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
return Promise.resolve();
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export const useInAppHandler = () => {
|
|
28
|
-
const [showInApp, setShowInApp] = useState(false);
|
|
29
|
-
|
|
30
|
-
useEffect(() => {
|
|
31
|
-
const checkInAppData = async () => {
|
|
32
|
-
const inAppData = await AsyncStorage.getItem('inapp');
|
|
33
|
-
if (inAppData) {
|
|
34
|
-
setShowInApp(true);
|
|
35
|
-
}
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
checkInAppData();
|
|
39
|
-
|
|
40
|
-
const subscription = AppState.addEventListener('change', nextAppState => {
|
|
41
|
-
if (nextAppState === 'active') {
|
|
42
|
-
checkInAppData();
|
|
43
|
-
}
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
return () => {
|
|
47
|
-
subscription.remove();
|
|
48
|
-
};
|
|
49
|
-
}, []);
|
|
50
|
-
|
|
51
|
-
return { showInApp, setShowInApp };
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export const InngageNotificationMessage = (firebaseListenCallback?: any) => {
|
|
55
|
-
const [notificationMessage, setNotificationMessage] = useState(null);
|
|
56
|
-
|
|
57
|
-
useEffect(() => {
|
|
58
|
-
PushNotification.configure({
|
|
59
|
-
onAction: function (data: any) {
|
|
60
|
-
console.log(data)
|
|
61
|
-
},
|
|
62
|
-
onNotification: function (data: any) {
|
|
63
|
-
if (data.foreground) {
|
|
64
|
-
if (notificationMessage) {
|
|
65
|
-
handleNotification(notificationMessage)
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
data.finish(PushNotificationIOS.FetchResult.NoData);
|
|
69
|
-
},
|
|
70
|
-
popInitialNotification: true,
|
|
71
|
-
requestPermissions: true
|
|
72
|
-
})
|
|
73
|
-
PushNotification.createChannel({
|
|
74
|
-
channelId: 'channel_id',
|
|
75
|
-
channelName: 'default',
|
|
76
|
-
importance: Importance.HIGH,
|
|
77
|
-
playSound: true,
|
|
78
|
-
soundName: 'default',
|
|
79
|
-
vibrate: true
|
|
80
|
-
}, (created: any) => {
|
|
81
|
-
if (created) {
|
|
82
|
-
console.log('Channel created');
|
|
83
|
-
}
|
|
84
|
-
});
|
|
85
|
-
})
|
|
86
|
-
useEffect(() => {
|
|
87
|
-
const handleMessage = async (remoteMessage: any) => {
|
|
88
|
-
const notificationData = remoteMessage.data;
|
|
89
|
-
|
|
90
|
-
if (notificationData.additional_data != null)
|
|
91
|
-
await AsyncStorage.setItem('inapp', notificationData.additional_data);
|
|
92
|
-
|
|
93
|
-
if (InngageProperties.getDebugMode())
|
|
94
|
-
console.log('Remote message received in foreground: ', remoteMessage);
|
|
95
|
-
|
|
96
|
-
if (firebaseListenCallback != null && remoteMessage != null)
|
|
97
|
-
firebaseListenCallback(notificationData)
|
|
98
|
-
|
|
99
|
-
setNotificationMessage(remoteMessage);
|
|
100
|
-
|
|
101
|
-
PushNotification.localNotification({
|
|
102
|
-
autoCancel: true,
|
|
103
|
-
bigPictureUrl: remoteMessage.notification?.android?.imageUrl,
|
|
104
|
-
largeIconUrl: remoteMessage.notification?.android?.imageUrl,
|
|
105
|
-
title: notificationData?.title,
|
|
106
|
-
message: notificationData?.body,
|
|
107
|
-
vibration: 300,
|
|
108
|
-
channelId: "channel_id",
|
|
109
|
-
});
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
return messaging().onMessage(handleMessage);
|
|
113
|
-
}, []);
|
|
114
|
-
|
|
115
|
-
useEffect(() => {
|
|
116
|
-
messaging().onNotificationOpenedApp(remoteMessage => {
|
|
117
|
-
if (remoteMessage != null)
|
|
118
|
-
firebaseListenCallback(remoteMessage.data)
|
|
119
|
-
|
|
120
|
-
handleNotification(remoteMessage)
|
|
121
|
-
})
|
|
122
|
-
}, []);
|
|
123
|
-
|
|
124
|
-
useEffect(() => {
|
|
125
|
-
messaging().getInitialNotification().then(async (value) => {
|
|
126
|
-
if (value !== null)
|
|
127
|
-
handleUniqueRemoteMessage(value);
|
|
128
|
-
});
|
|
129
|
-
}, [])
|
|
130
|
-
|
|
131
|
-
const handleUniqueRemoteMessage = async (
|
|
132
|
-
remoteMessage: { messageId?: string }) => {
|
|
133
|
-
try {
|
|
134
|
-
console.log('oi')
|
|
135
|
-
const lastRemoteMessageId = await AsyncStorage.getItem('LAST_REMOTE_MESSAGE_ID');
|
|
136
|
-
const newRemoteMessageId = remoteMessage?.messageId;
|
|
137
|
-
|
|
138
|
-
if (newRemoteMessageId && lastRemoteMessageId !== newRemoteMessageId) {
|
|
139
|
-
await AsyncStorage.setItem('LAST_REMOTE_MESSAGE_ID', newRemoteMessageId);
|
|
140
|
-
handleNotification(remoteMessage)
|
|
141
|
-
}
|
|
142
|
-
} catch (e) {
|
|
143
|
-
console.error(e);
|
|
144
|
-
}
|
|
145
|
-
};
|
|
146
|
-
|
|
147
|
-
async function handleNotification(remoteMessage) {
|
|
148
|
-
const notId = remoteMessage.data?.notId;
|
|
149
|
-
const request = {
|
|
150
|
-
notificationRequest: {
|
|
151
|
-
id: notId,
|
|
152
|
-
app_token: InngageProperties.appToken,
|
|
153
|
-
}
|
|
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
|
-
|
|
180
|
-
await ApiService.sendNotification(request);
|
|
181
|
-
}
|
|
182
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
export class InngageProperties {
|
|
2
|
-
static identifier: string = '';
|
|
3
|
-
static appToken: string = '';
|
|
4
|
-
static phoneNumber: string = '';
|
|
5
|
-
static email: string = '';
|
|
6
|
-
static customFields: any = {};
|
|
7
|
-
static blockDeepLink: boolean = false;
|
|
8
|
-
static debugMode: boolean = false;
|
|
9
|
-
static firebaseToken: string = '';
|
|
10
|
-
static getDebugMode(): boolean {
|
|
11
|
-
return InngageProperties.debugMode;
|
|
12
|
-
}
|
|
13
|
-
}
|