react-native-mobile-chat 0.1.0
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/LICENSE +20 -0
- package/README.md +235 -0
- package/android/build.gradle +77 -0
- package/android/gradle.properties +5 -0
- package/android/src/main/AndroidManifest.xml +4 -0
- package/android/src/main/java/com/appchat/AppChatModule.java +58 -0
- package/android/src/main/java/com/appchat/AppChatPackage.java +28 -0
- package/ios/AppChat.h +12 -0
- package/ios/AppChat.mm +67 -0
- package/ios/AppChat.xcodeproj/project.pbxproj +274 -0
- package/ios/AppChat.xcodeproj/project.xcworkspace/contents.xcworkspacedata +4 -0
- package/lib/commonjs/assets/images/arrow_left.png +0 -0
- package/lib/commonjs/assets/images/arrow_left_black.png +0 -0
- package/lib/commonjs/common/constants/index.js +20 -0
- package/lib/commonjs/common/constants/index.js.map +1 -0
- package/lib/commonjs/common/utils/index.js +53 -0
- package/lib/commonjs/common/utils/index.js.map +1 -0
- package/lib/commonjs/data/local/index.js +28 -0
- package/lib/commonjs/data/local/index.js.map +1 -0
- package/lib/commonjs/data/remote/index.js +87 -0
- package/lib/commonjs/data/remote/index.js.map +1 -0
- package/lib/commonjs/data/static/index.js +35 -0
- package/lib/commonjs/data/static/index.js.map +1 -0
- package/lib/commonjs/index.js +46 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/native/component/WebView.js +16 -0
- package/lib/commonjs/native/component/WebView.js.map +1 -0
- package/lib/commonjs/native/module/index.js +18 -0
- package/lib/commonjs/native/module/index.js.map +1 -0
- package/lib/commonjs/presentation/component/AppChatComponent.js +236 -0
- package/lib/commonjs/presentation/component/AppChatComponent.js.map +1 -0
- package/lib/commonjs/presentation/initialization/index.js +148 -0
- package/lib/commonjs/presentation/initialization/index.js.map +1 -0
- package/lib/commonjs/presentation/notification/index.js +50 -0
- package/lib/commonjs/presentation/notification/index.js.map +1 -0
- package/lib/module/assets/images/arrow_left.png +0 -0
- package/lib/module/assets/images/arrow_left_black.png +0 -0
- package/lib/module/common/constants/index.js +13 -0
- package/lib/module/common/constants/index.js.map +1 -0
- package/lib/module/common/utils/index.js +45 -0
- package/lib/module/common/utils/index.js.map +1 -0
- package/lib/module/data/local/index.js +20 -0
- package/lib/module/data/local/index.js.map +1 -0
- package/lib/module/data/remote/index.js +75 -0
- package/lib/module/data/remote/index.js.map +1 -0
- package/lib/module/data/static/index.js +28 -0
- package/lib/module/data/static/index.js.map +1 -0
- package/lib/module/index.js +5 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/native/component/WebView.js +10 -0
- package/lib/module/native/component/WebView.js.map +1 -0
- package/lib/module/native/module/index.js +11 -0
- package/lib/module/native/module/index.js.map +1 -0
- package/lib/module/presentation/component/AppChatComponent.js +227 -0
- package/lib/module/presentation/component/AppChatComponent.js.map +1 -0
- package/lib/module/presentation/initialization/index.js +141 -0
- package/lib/module/presentation/initialization/index.js.map +1 -0
- package/lib/module/presentation/notification/index.js +41 -0
- package/lib/module/presentation/notification/index.js.map +1 -0
- package/lib/typescript/common/constants/index.d.ts +13 -0
- package/lib/typescript/common/constants/index.d.ts.map +1 -0
- package/lib/typescript/common/utils/index.d.ts +15 -0
- package/lib/typescript/common/utils/index.d.ts.map +1 -0
- package/lib/typescript/data/local/index.d.ts +4 -0
- package/lib/typescript/data/local/index.d.ts.map +1 -0
- package/lib/typescript/data/remote/index.d.ts +7 -0
- package/lib/typescript/data/remote/index.d.ts.map +1 -0
- package/lib/typescript/data/static/index.d.ts +23 -0
- package/lib/typescript/data/static/index.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +5 -0
- package/lib/typescript/index.d.ts.map +1 -0
- package/lib/typescript/native/component/WebView.d.ts +8 -0
- package/lib/typescript/native/component/WebView.d.ts.map +1 -0
- package/lib/typescript/native/module/index.d.ts +2 -0
- package/lib/typescript/native/module/index.d.ts.map +1 -0
- package/lib/typescript/presentation/component/AppChatComponent.d.ts +22 -0
- package/lib/typescript/presentation/component/AppChatComponent.d.ts.map +1 -0
- package/lib/typescript/presentation/initialization/index.d.ts +2 -0
- package/lib/typescript/presentation/initialization/index.d.ts.map +1 -0
- package/lib/typescript/presentation/notification/index.d.ts +5 -0
- package/lib/typescript/presentation/notification/index.d.ts.map +1 -0
- package/package.json +165 -0
- package/react-native-app-chat.podspec +35 -0
- package/src/assets/images/arrow_left.png +0 -0
- package/src/assets/images/arrow_left_black.png +0 -0
- package/src/common/constants/index.tsx +12 -0
- package/src/common/utils/index.tsx +58 -0
- package/src/data/local/index.tsx +23 -0
- package/src/data/remote/index.tsx +80 -0
- package/src/data/static/index.tsx +28 -0
- package/src/index.tsx +11 -0
- package/src/native/component/WebView.tsx +10 -0
- package/src/native/module/index.tsx +18 -0
- package/src/presentation/component/AppChatComponent.tsx +154 -0
- package/src/presentation/initialization/index.tsx +149 -0
- package/src/presentation/notification/index.tsx +45 -0
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import React, { PureComponent, ReactNode, Fragment } from 'react';
|
|
2
|
+
import { ActivityIndicator, StatusBar, View, Dimensions, Text, TouchableOpacity, Image, PermissionsAndroid, Platform } from 'react-native';
|
|
3
|
+
import { AppChatStatic } from '../../data/static';
|
|
4
|
+
import { initAppChat } from '../../presentation/initialization';
|
|
5
|
+
import WebView, { WebViewMessageEvent } from 'react-native-webview';
|
|
6
|
+
import Constant from '../../common/constants';
|
|
7
|
+
import { putString } from '../../data/local';
|
|
8
|
+
import { SafeAreaView } from 'react-native';
|
|
9
|
+
|
|
10
|
+
type AppChatComponentProps = {
|
|
11
|
+
onBackButtonTapped: () => void
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export default class AppChatComponent extends PureComponent<AppChatComponentProps> {
|
|
15
|
+
|
|
16
|
+
_isMounted = false
|
|
17
|
+
|
|
18
|
+
state = {
|
|
19
|
+
isOverlaid: false,
|
|
20
|
+
toggleRefresh: false
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
constructor(props: AppChatComponentProps) {
|
|
24
|
+
super(props)
|
|
25
|
+
this.state = {
|
|
26
|
+
isOverlaid: false,
|
|
27
|
+
toggleRefresh: false
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
_setState = (state: any) => {
|
|
32
|
+
if (this._isMounted) {
|
|
33
|
+
this.setState(state)
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
_requestPermission = async (permission: any) => {
|
|
38
|
+
if (Platform.OS == 'android') {
|
|
39
|
+
const granted = await PermissionsAndroid.check(permission)
|
|
40
|
+
if (!granted) {
|
|
41
|
+
PermissionsAndroid.request(permission)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
_onAccessTokenExpired = async () => {
|
|
47
|
+
AppChatStatic.initAppChatResult = ''
|
|
48
|
+
AppChatStatic.accessToken = ''
|
|
49
|
+
AppChatStatic.encryptedUrlParams = ''
|
|
50
|
+
await putString('accessToken', 'default_value')
|
|
51
|
+
this._setState({ toggleRefresh: !this.state.toggleRefresh })
|
|
52
|
+
this.componentDidMount()
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
_onMessage = (event: WebViewMessageEvent) => {
|
|
56
|
+
const data = JSON.parse(event.nativeEvent.data)
|
|
57
|
+
switch (data.key) {
|
|
58
|
+
case 'TOKEN_EXPIRED':
|
|
59
|
+
this._onAccessTokenExpired()
|
|
60
|
+
break;
|
|
61
|
+
case 'OVERLAY':
|
|
62
|
+
this._setState({ isOverlaid: true })
|
|
63
|
+
this._requestPermission('android.permission.CAMERA')
|
|
64
|
+
break;
|
|
65
|
+
case 'REMOVE_OVERLAY':
|
|
66
|
+
this._setState({ isOverlaid: false })
|
|
67
|
+
break;
|
|
68
|
+
case 'CAMERA':
|
|
69
|
+
//this._requestPermission('android.permission.RECORD_AUDIO')
|
|
70
|
+
break;
|
|
71
|
+
case 'GALLERY':
|
|
72
|
+
//this._requestPermission('android.permission.READ_MEDIA_IMAGES')
|
|
73
|
+
//this._requestPermission('android.permission.READ_MEDIA_VIDEO')
|
|
74
|
+
break;
|
|
75
|
+
case 'DOCUMENT':
|
|
76
|
+
//this._requestPermission('android.permission.READ_EXTERNAL_STORAGE')
|
|
77
|
+
break;
|
|
78
|
+
case 'AUDIO':
|
|
79
|
+
//this._requestPermission('android.permission.READ_MEDIA_AUDIO')
|
|
80
|
+
break;
|
|
81
|
+
default:
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
84
|
+
console.log('onMessage', event.nativeEvent.data);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
componentDidMount(): void {
|
|
88
|
+
this._isMounted = true
|
|
89
|
+
AppChatStatic.appChatOpened = true
|
|
90
|
+
if (AppChatStatic.initAppChatResult === '') {
|
|
91
|
+
setTimeout(() => {
|
|
92
|
+
const { appId, clientId, clientSecret, externalId, fullName } = AppChatStatic
|
|
93
|
+
initAppChat(appId, clientId, clientSecret, externalId, fullName).then((result) => {
|
|
94
|
+
if (result === 'SUCCESS') this._setState({ toggleRefresh: !this.state.toggleRefresh })
|
|
95
|
+
})
|
|
96
|
+
}, 10000);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
componentWillUnmount(): void {
|
|
101
|
+
this._isMounted = false
|
|
102
|
+
AppChatStatic.appChatOpened = false
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
render(): ReactNode {
|
|
106
|
+
const { onBackButtonTapped } = this.props
|
|
107
|
+
const { initAppChatResult, bundleIdValidation } = AppChatStatic
|
|
108
|
+
const { bgColorTheme, textHeader, textDescription, fontColor } = AppChatStatic.appChatTheme
|
|
109
|
+
const postMessageListener = `window.addEventListener('message',(event) => window.ReactNativeWebView.postMessage(event.data));let meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0'); document.getElementsByTagName('head')[0].appendChild(meta);`;
|
|
110
|
+
if (initAppChatResult === 'SUCCESS' && bundleIdValidation !== 'success') {
|
|
111
|
+
return (
|
|
112
|
+
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
|
|
113
|
+
<Text style={{ textAlign: 'center', padding: 16 }}>{Constant.BUNDLE_ID_INVALID} </Text>
|
|
114
|
+
</View>
|
|
115
|
+
)
|
|
116
|
+
}
|
|
117
|
+
return (
|
|
118
|
+
<Fragment>
|
|
119
|
+
<SafeAreaView style={{ flex: 0, backgroundColor: this.state.isOverlaid ? AppChatStatic.appChatTheme.bgColorThemeOverlaid : bgColorTheme }} />
|
|
120
|
+
<SafeAreaView style={{ flex: 1, backgroundColor: this.state.isOverlaid ? Constant.WEBVIEW_BACKGROUND_COLOR_OVERLAID : Constant.WEBVIEW_BACKGROUND_COLOR }}>
|
|
121
|
+
<StatusBar
|
|
122
|
+
barStyle={fontColor === 'black' || this.state.isOverlaid ? 'dark-content' : 'light-content'}
|
|
123
|
+
backgroundColor={this.state.isOverlaid ? AppChatStatic.appChatTheme.bgColorThemeOverlaid : bgColorTheme}
|
|
124
|
+
/>
|
|
125
|
+
<View style={{ height: 52, backgroundColor: bgColorTheme }}>
|
|
126
|
+
<View style={{ position: 'absolute' }}>
|
|
127
|
+
<View style={{ position: 'absolute', top: 0, flexDirection: 'row', height: 52, width: Dimensions.get('screen').width, backgroundColor: bgColorTheme }}>
|
|
128
|
+
<TouchableOpacity style={{ width: 52, height: 52, justifyContent: 'center', alignItems: 'center' }} onPress={() => onBackButtonTapped()} >
|
|
129
|
+
<Image style={{ height: 16 }} source={fontColor === 'black' ? require('../../assets/images/arrow_left_black.png') : require('../../assets/images/arrow_left.png')} />
|
|
130
|
+
</TouchableOpacity>
|
|
131
|
+
<View style={{ height: 52, justifyContent: 'center', alignItems: 'flex-start' }}>
|
|
132
|
+
<Text style={{ fontSize: 16, color: fontColor, fontWeight: '600' }}>{textHeader}</Text>
|
|
133
|
+
<Text style={{ fontSize: 12, color: fontColor, fontWeight: '400' }}>{textDescription}</Text>
|
|
134
|
+
</View>
|
|
135
|
+
</View>
|
|
136
|
+
{this.state.isOverlaid && <View style={{ position: 'absolute', top: 0, height: 52, width: Dimensions.get('screen').width, backgroundColor: 'rgba(35, 41, 51, 0.8)' }} />}
|
|
137
|
+
</View>
|
|
138
|
+
</View>
|
|
139
|
+
{AppChatStatic.initAppChatResult !== 'SUCCESS' && <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
|
|
140
|
+
<ActivityIndicator size="large" />
|
|
141
|
+
</View>}
|
|
142
|
+
{AppChatStatic.initAppChatResult === 'SUCCESS' && <WebView
|
|
143
|
+
bounces={false}
|
|
144
|
+
overScrollMode='never'
|
|
145
|
+
setBuiltInZoomControls={false}
|
|
146
|
+
injectedJavaScriptBeforeContentLoaded={postMessageListener}
|
|
147
|
+
source={{ uri: `${Constant.BASE_URL_WEBVIEW}${Constant.ENCRYPTED_PARAMS_KEY}${AppChatStatic.encryptedUrlParams}` }}
|
|
148
|
+
onMessage={this._onMessage}
|
|
149
|
+
style={{ flex: 1, backgroundColor: this.state.isOverlaid ? Constant.WEBVIEW_BACKGROUND_COLOR_OVERLAID : Constant.WEBVIEW_BACKGROUND_COLOR }} />}
|
|
150
|
+
</SafeAreaView>
|
|
151
|
+
</Fragment>
|
|
152
|
+
)
|
|
153
|
+
}
|
|
154
|
+
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { getBundleIdOrPackageName, getString, putString } from "../../data/local"
|
|
2
|
+
import { authenticate, createContact, getWidgetSetting, registerFcmToken, validateBundleId } from "../../data/remote"
|
|
3
|
+
import { AppChatStatic } from "../../data/static"
|
|
4
|
+
import { calculateTextColorOutput, getEncryptedUrlParams, getOverlaidColor } from '../../common/utils';
|
|
5
|
+
import Constant from "../../common/constants";
|
|
6
|
+
|
|
7
|
+
export async function initAppChat(appId: string, clientId: string, clientSecret: string, externalId: string, fullName: string) {
|
|
8
|
+
AppChatStatic.appId = appId
|
|
9
|
+
AppChatStatic.clientId = clientId
|
|
10
|
+
AppChatStatic.clientSecret = clientSecret
|
|
11
|
+
AppChatStatic.externalId = externalId
|
|
12
|
+
AppChatStatic.fullName = fullName
|
|
13
|
+
|
|
14
|
+
//is client app re-login?
|
|
15
|
+
const currentExternalId = await getString('externalId')
|
|
16
|
+
if (currentExternalId !== externalId) {
|
|
17
|
+
AppChatStatic.accessToken = ''
|
|
18
|
+
AppChatStatic.contactId = ''
|
|
19
|
+
AppChatStatic.bundleIdValidation = ''
|
|
20
|
+
AppChatStatic.encryptedUrlParams = ''
|
|
21
|
+
AppChatStatic.initAppChatResult = ''
|
|
22
|
+
|
|
23
|
+
AppChatStatic.appChatTheme.bgColorTheme = 'grey'
|
|
24
|
+
AppChatStatic.appChatTheme.fontColor = 'white'
|
|
25
|
+
AppChatStatic.appChatTheme.textHeader = ''
|
|
26
|
+
AppChatStatic.appChatTheme.textDescription = ''
|
|
27
|
+
|
|
28
|
+
AppChatStatic.fcmToken = ''
|
|
29
|
+
|
|
30
|
+
await putString('accessToken', 'default_value')
|
|
31
|
+
await putString('fcmToken', 'default_value')
|
|
32
|
+
await putString('contactId', 'default_value')
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
try {
|
|
36
|
+
//Authentication - accessToken
|
|
37
|
+
const accessToken = AppChatStatic.accessToken == '' ? await updateAccessToken(clientId, clientSecret) : AppChatStatic.accessToken
|
|
38
|
+
|
|
39
|
+
//Create Contact - contactId
|
|
40
|
+
const contactId = AppChatStatic.contactId == '' ? await updateContactId(externalId, fullName) : AppChatStatic.contactId
|
|
41
|
+
|
|
42
|
+
//Validate Bundle ID or Package Name - bundleIdValidation
|
|
43
|
+
const bundleIdValidation = AppChatStatic.bundleIdValidation !== 'success' ? await validateBundleIdOrPackageName() : AppChatStatic.bundleIdValidation
|
|
44
|
+
|
|
45
|
+
//Encrypt URL Params - encryptedUrlParams
|
|
46
|
+
const encryptedUrlParams = AppChatStatic.encryptedUrlParams == '' ? updateEncryptedUrlParams() : AppChatStatic.encryptedUrlParams
|
|
47
|
+
|
|
48
|
+
//Get theme - appChatTheme
|
|
49
|
+
AppChatStatic.appChatTheme.isAnyEmpty() ? await updateAppChatTheme() : AppChatStatic.appChatTheme
|
|
50
|
+
|
|
51
|
+
//Register notif
|
|
52
|
+
if (AppChatStatic.fcmToken != '') {
|
|
53
|
+
const response = await registerFcmToken(AppChatStatic.fcmToken)
|
|
54
|
+
if (response.ok) {
|
|
55
|
+
await putString('fcmToken', AppChatStatic.fcmToken)
|
|
56
|
+
console.log("FCM token registration success, user can receive notification");
|
|
57
|
+
} else {
|
|
58
|
+
console.log("FCM token registration failed, user can't receive notification");
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
//Save result- initAppChatResult
|
|
64
|
+
if (accessToken != '' && contactId != '' && bundleIdValidation != '' && encryptedUrlParams != '' && !AppChatStatic.appChatTheme.isAnyEmpty()) AppChatStatic.initAppChatResult = 'SUCCESS'
|
|
65
|
+
else AppChatStatic.initAppChatResult = 'FAILED'
|
|
66
|
+
if (AppChatStatic.initAppChatResult === 'SUCCESS') await putString('externalId', externalId)
|
|
67
|
+
return AppChatStatic.initAppChatResult
|
|
68
|
+
} catch (error) {
|
|
69
|
+
return JSON.stringify(error)
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
async function updateAccessToken(clientId: string, clientSecret: string) {
|
|
74
|
+
const accessToken = await getString('accessToken')
|
|
75
|
+
if (accessToken) {
|
|
76
|
+
AppChatStatic.accessToken = accessToken
|
|
77
|
+
} else {
|
|
78
|
+
const authResponse = await authenticate(clientId, clientSecret)
|
|
79
|
+
const authData = await authResponse.json()
|
|
80
|
+
if (!authResponse.ok) return authResponse.status
|
|
81
|
+
AppChatStatic.accessToken = authData['access_token']
|
|
82
|
+
await putString('accessToken', AppChatStatic.accessToken)
|
|
83
|
+
}
|
|
84
|
+
return AppChatStatic.accessToken
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async function updateContactId(externalId: string, fullName: string) {
|
|
88
|
+
const contactId = await getString('contactId')
|
|
89
|
+
if (contactId) {
|
|
90
|
+
AppChatStatic.contactId = contactId
|
|
91
|
+
} else {
|
|
92
|
+
const createContactResponse = await createContact(externalId, fullName)
|
|
93
|
+
if (!createContactResponse.ok) return createContactResponse.status
|
|
94
|
+
const createContactData = await createContactResponse.json()
|
|
95
|
+
AppChatStatic.contactId = createContactData.data['id']
|
|
96
|
+
await putString('contactId', AppChatStatic.contactId)
|
|
97
|
+
}
|
|
98
|
+
return AppChatStatic.contactId
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
async function validateBundleIdOrPackageName() {
|
|
102
|
+
const bundleIdValidation = await getString('bundleIdValidation')
|
|
103
|
+
let errorCode = undefined
|
|
104
|
+
let errorMessage = undefined
|
|
105
|
+
if (bundleIdValidation != 'success') {
|
|
106
|
+
const bundleId = await getBundleIdOrPackageName()
|
|
107
|
+
if (bundleId) {
|
|
108
|
+
const validateBundleIdResponse = await validateBundleId(bundleId)
|
|
109
|
+
const validateBundleIdData = await validateBundleIdResponse.json()
|
|
110
|
+
if (validateBundleIdResponse.ok) {
|
|
111
|
+
AppChatStatic.bundleIdValidation = validateBundleIdData?.data?.status === 'success' ? 'success' : 'failed'
|
|
112
|
+
if (AppChatStatic.bundleIdValidation == 'success') await putString('bundleIdValidation', 'success')
|
|
113
|
+
} else {
|
|
114
|
+
errorCode = validateBundleIdResponse.status
|
|
115
|
+
errorMessage = validateBundleIdData?.error?.messages[0]
|
|
116
|
+
AppChatStatic.bundleIdValidation = 'failed'
|
|
117
|
+
}
|
|
118
|
+
} else {
|
|
119
|
+
AppChatStatic.bundleIdValidation = 'not available'
|
|
120
|
+
}
|
|
121
|
+
} else {
|
|
122
|
+
AppChatStatic.bundleIdValidation = bundleIdValidation
|
|
123
|
+
}
|
|
124
|
+
if (AppChatStatic.bundleIdValidation != 'success' && AppChatStatic.bundleIdValidation != '') {
|
|
125
|
+
console.log(`${Constant.BUNDLE_ID_INVALID}\n${errorCode ?? ''} ${errorMessage ?? ''}`)
|
|
126
|
+
}
|
|
127
|
+
return AppChatStatic.bundleIdValidation
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function updateEncryptedUrlParams() {
|
|
131
|
+
AppChatStatic.encryptedUrlParams = getEncryptedUrlParams({
|
|
132
|
+
access_token: AppChatStatic.accessToken,
|
|
133
|
+
app_id: AppChatStatic.appId,
|
|
134
|
+
contact_id: AppChatStatic.contactId
|
|
135
|
+
})
|
|
136
|
+
return AppChatStatic.encryptedUrlParams
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
async function updateAppChatTheme() {
|
|
140
|
+
const response = await getWidgetSetting()
|
|
141
|
+
const data = (await response.json())?.data
|
|
142
|
+
if (!response.ok) return response.status
|
|
143
|
+
AppChatStatic.appChatTheme.bgColorTheme = data.style?.theme?.bg_color
|
|
144
|
+
AppChatStatic.appChatTheme.bgColorThemeOverlaid = getOverlaidColor(AppChatStatic.appChatTheme.bgColorTheme, Constant.OVERLAY_COLOR, Constant.OVERLAY_OPACITY)
|
|
145
|
+
AppChatStatic.appChatTheme.fontColor = calculateTextColorOutput(AppChatStatic.appChatTheme.bgColorTheme)
|
|
146
|
+
AppChatStatic.appChatTheme.textHeader = data.header?.text
|
|
147
|
+
AppChatStatic.appChatTheme.textDescription = data.description?.text
|
|
148
|
+
return AppChatStatic.appChatTheme
|
|
149
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { getString, putString } from "../../data/local"
|
|
2
|
+
import { registerFcmToken, revokeFcmToken } from "../../data/remote"
|
|
3
|
+
import { AppChatStatic } from "../../data/static"
|
|
4
|
+
|
|
5
|
+
export async function registerNotification(fcmToken: string) {
|
|
6
|
+
const localFcmToken = await getString('fcmToken')
|
|
7
|
+
if (fcmToken === localFcmToken) return
|
|
8
|
+
if (AppChatStatic.initAppChatResult !== 'success') {
|
|
9
|
+
AppChatStatic.fcmToken = fcmToken
|
|
10
|
+
return "FCM token registration : waiting initialization success"
|
|
11
|
+
} else {
|
|
12
|
+
const response = await registerFcmToken(fcmToken)
|
|
13
|
+
if (response.ok) {
|
|
14
|
+
await putString('fcmToken', fcmToken)
|
|
15
|
+
return "FCM token registration success, user can receive notification"
|
|
16
|
+
} else {
|
|
17
|
+
return "FCM token registration failed, user can't receive notification"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export async function revokeNotification() {
|
|
23
|
+
const localFcmToken = await getString('fcmToken')
|
|
24
|
+
if (localFcmToken == null) return
|
|
25
|
+
const response = await revokeFcmToken(localFcmToken)
|
|
26
|
+
if (response.ok) {
|
|
27
|
+
AppChatStatic.fcmToken = ''
|
|
28
|
+
return "Revoke FCM token success"
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
return "Revoke FCM token failed"
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function isAppChatPayload(payload: any): boolean {
|
|
36
|
+
if (payload?.data == null) {
|
|
37
|
+
return false;
|
|
38
|
+
} else {
|
|
39
|
+
return payload.data['notification_source'] == 'app-chat-qontak';
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function isAppChatOpened(): boolean {
|
|
44
|
+
return AppChatStatic.appChatOpened;
|
|
45
|
+
}
|