react-native-mytatva-rn-sdk 1.0.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 +31 -0
- package/android/build.gradle +112 -0
- package/android/gradle.properties +5 -0
- package/android/src/main/AndroidManifest.xml +3 -0
- package/android/src/main/AndroidManifestNew.xml +2 -0
- package/android/src/main/java/com/visitrnsdk/VisitRnSdkPackage.kt +17 -0
- package/android/src/main/java/com/visitrnsdk/VisitRnSdkViewManager.kt +20 -0
- package/ios/VisitRnSdk.xcodeproj/project.pbxproj +274 -0
- package/ios/VisitRnSdkViewManager.h +20 -0
- package/ios/VisitRnSdkViewManager.m +1240 -0
- package/lib/commonjs/Services.js +35 -0
- package/lib/commonjs/Services.js.map +1 -0
- package/lib/commonjs/constants.js +11 -0
- package/lib/commonjs/constants.js.map +1 -0
- package/lib/commonjs/index.android.js +518 -0
- package/lib/commonjs/index.android.js.map +1 -0
- package/lib/commonjs/index.ios.js +313 -0
- package/lib/commonjs/index.ios.js.map +1 -0
- package/lib/module/Services.js +27 -0
- package/lib/module/Services.js.map +1 -0
- package/lib/module/constants.js +5 -0
- package/lib/module/constants.js.map +1 -0
- package/lib/module/index.android.js +508 -0
- package/lib/module/index.android.js.map +1 -0
- package/lib/module/index.ios.js +304 -0
- package/lib/module/index.ios.js.map +1 -0
- package/lib/typescript/index.test.d.ts +1 -0
- package/lib/typescript/index.test.d.ts.map +1 -0
- package/package.json +177 -0
- package/react-native-visit-rn-sdk.podspec +42 -0
- package/src/Services.js +37 -0
- package/src/constants.js +4 -0
- package/src/index.android.js +714 -0
- package/src/index.ios.js +376 -0
package/src/index.ios.js
ADDED
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
import React, {
|
|
2
|
+
useRef,
|
|
3
|
+
useEffect,
|
|
4
|
+
useState,
|
|
5
|
+
useCallback,
|
|
6
|
+
useMemo,
|
|
7
|
+
} from 'react';
|
|
8
|
+
import {
|
|
9
|
+
StyleSheet,
|
|
10
|
+
SafeAreaView,
|
|
11
|
+
NativeModules,
|
|
12
|
+
NativeEventEmitter,
|
|
13
|
+
Linking,
|
|
14
|
+
Platform,
|
|
15
|
+
ActivityIndicator,
|
|
16
|
+
Dimensions,
|
|
17
|
+
} from 'react-native';
|
|
18
|
+
import { EventRegister } from 'react-native-event-listeners';
|
|
19
|
+
import { WebView } from 'react-native-webview';
|
|
20
|
+
import DeviceInfo from 'react-native-device-info';
|
|
21
|
+
import { getWebViewLink, httpClient } from './Services';
|
|
22
|
+
import constants from './constants';
|
|
23
|
+
|
|
24
|
+
const LINKING_ERROR =
|
|
25
|
+
`The package 'react-native-mytatva-rn-sdk' doesn't seem to be linked. Make sure: \n\n` +
|
|
26
|
+
Platform.select({ ios: "- You have run 'pod install'\n", default: '' }) +
|
|
27
|
+
'- You rebuilt the app after installing the package\n' +
|
|
28
|
+
'- You are not using Expo Go\n';
|
|
29
|
+
|
|
30
|
+
const escapeChars = {
|
|
31
|
+
lt: '<',
|
|
32
|
+
gt: '>',
|
|
33
|
+
quot: '"',
|
|
34
|
+
apos: "'",
|
|
35
|
+
amp: '&',
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const unescapeHTML = (str) =>
|
|
39
|
+
// modified from underscore.string and string.js
|
|
40
|
+
// eslint-disable-next-line no-useless-escape
|
|
41
|
+
str.replace(/\&([^;]+);/g, (entity, entityCode) => {
|
|
42
|
+
let match;
|
|
43
|
+
|
|
44
|
+
if (entityCode in escapeChars) {
|
|
45
|
+
return escapeChars[entityCode];
|
|
46
|
+
} else if ((match = entityCode.match(/^#x([\da-fA-F]+)$/))) {
|
|
47
|
+
return String.fromCharCode(parseInt(match[1], 16));
|
|
48
|
+
} else if ((match = entityCode.match(/^#(\d+)$/))) {
|
|
49
|
+
return String.fromCharCode(match[1]);
|
|
50
|
+
} else {
|
|
51
|
+
return entity;
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
const visitEvent = 'visit-event';
|
|
56
|
+
|
|
57
|
+
const MyTatvaRnSdkView = ({
|
|
58
|
+
cpsid,
|
|
59
|
+
baseUrl,
|
|
60
|
+
errorBaseUrl,
|
|
61
|
+
token,
|
|
62
|
+
moduleName,
|
|
63
|
+
environment,
|
|
64
|
+
magicLink,
|
|
65
|
+
isLoggingEnabled,
|
|
66
|
+
}) => {
|
|
67
|
+
const [source, setSource] = useState('');
|
|
68
|
+
const [loading, setLoading] = useState(true);
|
|
69
|
+
useEffect(() => {
|
|
70
|
+
if (magicLink?.trim()?.length) {
|
|
71
|
+
setSource(magicLink);
|
|
72
|
+
setLoading(false);
|
|
73
|
+
} else {
|
|
74
|
+
const systemVersion = DeviceInfo.getSystemVersion();
|
|
75
|
+
const version = DeviceInfo.getVersion();
|
|
76
|
+
DeviceInfo.getUniqueId()
|
|
77
|
+
.then((uniqueId) =>
|
|
78
|
+
getWebViewLink(
|
|
79
|
+
baseUrl,
|
|
80
|
+
token,
|
|
81
|
+
cpsid,
|
|
82
|
+
'iPhone',
|
|
83
|
+
uniqueId,
|
|
84
|
+
version,
|
|
85
|
+
systemVersion,
|
|
86
|
+
environment
|
|
87
|
+
)
|
|
88
|
+
)
|
|
89
|
+
.then((res) => {
|
|
90
|
+
if (res.data?.errorMessage) {
|
|
91
|
+
const { errorMessage } = res.data;
|
|
92
|
+
const errorUrl = `${errorBaseUrl}/star-health?error=${errorMessage}`;
|
|
93
|
+
setSource(errorUrl);
|
|
94
|
+
if (res.data?.errorMessage === 'Please login again') {
|
|
95
|
+
EventRegister.emitEvent(visitEvent, {
|
|
96
|
+
message: 'unauthorized-wellness-access',
|
|
97
|
+
errorMessage: errorMessage,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
if (res.data?.errorMessage.includes('External Server Error')) {
|
|
101
|
+
EventRegister.emitEvent('visit-event', {
|
|
102
|
+
message: 'external-server-error',
|
|
103
|
+
errorMessage: errorMessage,
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
} else if (res.data.message === 'success') {
|
|
107
|
+
const magicCode = res.data?.magicCode;
|
|
108
|
+
const responseReferenceId = res.data?.responseReferenceId;
|
|
109
|
+
let finalBaseUrl = '';
|
|
110
|
+
if (magicCode) {
|
|
111
|
+
if (environment.toUpperCase() === 'PROD') {
|
|
112
|
+
finalBaseUrl = constants.PROD_BASE_URL;
|
|
113
|
+
} else {
|
|
114
|
+
finalBaseUrl = constants.STAGE_BASE_URL;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
if (finalBaseUrl && magicCode) {
|
|
118
|
+
let finalUrl = `${finalBaseUrl}=${magicCode}`;
|
|
119
|
+
if (moduleName?.trim()) {
|
|
120
|
+
finalUrl += `&tab=${moduleName}`;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (
|
|
124
|
+
typeof responseReferenceId === 'string' &&
|
|
125
|
+
responseReferenceId.trim().length > 0
|
|
126
|
+
) {
|
|
127
|
+
finalUrl += `&responseReferenceId=${responseReferenceId}`;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
setSource(finalUrl);
|
|
131
|
+
}
|
|
132
|
+
} else {
|
|
133
|
+
EventRegister.emitEvent('visit-event', {
|
|
134
|
+
message: 'generate-magic-link-failed',
|
|
135
|
+
errorMessage: `${res.data}`,
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
})
|
|
139
|
+
.catch((err) => {
|
|
140
|
+
console.log('getWebViewLink err', { err });
|
|
141
|
+
EventRegister.emitEvent('visit-event', {
|
|
142
|
+
message: 'generate-magic-link-failed',
|
|
143
|
+
errorMessage: `${err}`,
|
|
144
|
+
});
|
|
145
|
+
})
|
|
146
|
+
.finally(() => {
|
|
147
|
+
setLoading(false);
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
}, [
|
|
151
|
+
cpsid,
|
|
152
|
+
token,
|
|
153
|
+
baseUrl,
|
|
154
|
+
errorBaseUrl,
|
|
155
|
+
moduleName,
|
|
156
|
+
environment,
|
|
157
|
+
magicLink,
|
|
158
|
+
isLoggingEnabled,
|
|
159
|
+
]);
|
|
160
|
+
|
|
161
|
+
const MyTatvaRnSdkViewManager = useMemo(
|
|
162
|
+
() =>
|
|
163
|
+
NativeModules.MyTatvaRnSdkViewManager
|
|
164
|
+
? NativeModules.MyTatvaRnSdkViewManager
|
|
165
|
+
: new Proxy(
|
|
166
|
+
{},
|
|
167
|
+
{
|
|
168
|
+
get() {
|
|
169
|
+
throw new Error(LINKING_ERROR);
|
|
170
|
+
},
|
|
171
|
+
}
|
|
172
|
+
),
|
|
173
|
+
[]
|
|
174
|
+
);
|
|
175
|
+
|
|
176
|
+
const webviewRef = useRef(null);
|
|
177
|
+
const [apiBaseUrl, setApiBaseUrl] = useState('');
|
|
178
|
+
const [authToken, setAuthToken] = useState('');
|
|
179
|
+
const [hasLoadedOnce, setHasLoadedOnce] = useState(false);
|
|
180
|
+
|
|
181
|
+
const callSyncApi = useCallback(
|
|
182
|
+
(data) =>
|
|
183
|
+
httpClient
|
|
184
|
+
.post(`${apiBaseUrl}/users/data-sync`, data, {
|
|
185
|
+
headers: {
|
|
186
|
+
Authorization: authToken,
|
|
187
|
+
},
|
|
188
|
+
})
|
|
189
|
+
.then((res) => console.log('callSyncData response,', res))
|
|
190
|
+
.catch((err) => console.log('callSyncData err,', { err })),
|
|
191
|
+
[apiBaseUrl, authToken]
|
|
192
|
+
);
|
|
193
|
+
|
|
194
|
+
const callEmbellishApi = useCallback(
|
|
195
|
+
(data) =>
|
|
196
|
+
httpClient
|
|
197
|
+
.post(`${apiBaseUrl}/users/embellish-sync`, data, {
|
|
198
|
+
headers: {
|
|
199
|
+
Authorization: authToken,
|
|
200
|
+
},
|
|
201
|
+
})
|
|
202
|
+
.then((res) => console.log('callEmbellishApi response,', res))
|
|
203
|
+
.catch((err) => console.log('callEmbellishApi err,', { err })),
|
|
204
|
+
[apiBaseUrl, authToken]
|
|
205
|
+
);
|
|
206
|
+
|
|
207
|
+
useEffect(() => {
|
|
208
|
+
const apiManagerEmitter = new NativeEventEmitter(MyTatvaRnSdkViewManager);
|
|
209
|
+
const subscription = apiManagerEmitter.addListener(
|
|
210
|
+
'EventReminder',
|
|
211
|
+
(reminder) => {
|
|
212
|
+
if (reminder?.callSyncData && reminder?.callSyncData?.length) {
|
|
213
|
+
callSyncApi(reminder?.callSyncData[0]);
|
|
214
|
+
}
|
|
215
|
+
if (reminder?.callEmbellishApi && reminder?.callEmbellishApi?.length) {
|
|
216
|
+
callEmbellishApi(reminder?.callEmbellishApi[0]);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
);
|
|
220
|
+
return () => {
|
|
221
|
+
subscription.remove();
|
|
222
|
+
};
|
|
223
|
+
}, [MyTatvaRnSdkViewManager, callEmbellishApi, callSyncApi]);
|
|
224
|
+
|
|
225
|
+
const handleMessage = async (event) => {
|
|
226
|
+
const data = JSON.parse(unescapeHTML(event.nativeEvent.data));
|
|
227
|
+
const {
|
|
228
|
+
method,
|
|
229
|
+
type,
|
|
230
|
+
frequency,
|
|
231
|
+
timestamp,
|
|
232
|
+
// eslint-disable-next-line no-shadow
|
|
233
|
+
apiBaseUrl,
|
|
234
|
+
authtoken,
|
|
235
|
+
googleFitLastSync,
|
|
236
|
+
gfHourlyLastSync,
|
|
237
|
+
url,
|
|
238
|
+
} = data;
|
|
239
|
+
console.log('handleMessage data is', data);
|
|
240
|
+
console.log(unescapeHTML(event.nativeEvent.data));
|
|
241
|
+
switch (method) {
|
|
242
|
+
case 'UPDATE_PLATFORM':
|
|
243
|
+
webviewRef.current?.injectJavaScript('window.setSdkPlatform("IOS")');
|
|
244
|
+
break;
|
|
245
|
+
case 'CONNECT_TO_GOOGLE_FIT':
|
|
246
|
+
if (DeviceInfo.getModel() === 'iPad') {
|
|
247
|
+
console.log('unsupportedHealthKitDevice triggered');
|
|
248
|
+
webviewRef.current?.injectJavaScript(
|
|
249
|
+
'window.unsupportedHealthKitDevice(true)'
|
|
250
|
+
);
|
|
251
|
+
} else {
|
|
252
|
+
MyTatvaRnSdkViewManager?.connectToAppleHealth((res) => {
|
|
253
|
+
if (res?.sleepTime || res?.numberOfSteps) {
|
|
254
|
+
webviewRef.current?.injectJavaScript(
|
|
255
|
+
`window.updateFitnessPermissions(true,${res?.numberOfSteps},${res?.sleepTime})`
|
|
256
|
+
);
|
|
257
|
+
} else {
|
|
258
|
+
webviewRef.current?.injectJavaScript(
|
|
259
|
+
'window.updateFitnessPermissions(true,0,0)'
|
|
260
|
+
);
|
|
261
|
+
}
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
break;
|
|
265
|
+
case 'GET_DATA_TO_GENERATE_GRAPH':
|
|
266
|
+
MyTatvaRnSdkViewManager?.renderGraph(
|
|
267
|
+
{ type, frequency, timestamp },
|
|
268
|
+
(err, results) => {
|
|
269
|
+
if (err) {
|
|
270
|
+
console.log('error initializing Healthkit: ', err);
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
if (results[0]) {
|
|
274
|
+
console.log('results initializing Healthkit: ', results[0]);
|
|
275
|
+
webviewRef.current?.injectJavaScript(`window.${results[0]}`);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
);
|
|
279
|
+
break;
|
|
280
|
+
case 'UPDATE_API_BASE_URL':
|
|
281
|
+
if (!hasLoadedOnce) {
|
|
282
|
+
console.log('apiBaseUrl is,', apiBaseUrl);
|
|
283
|
+
setApiBaseUrl(apiBaseUrl);
|
|
284
|
+
setAuthToken(authtoken);
|
|
285
|
+
MyTatvaRnSdkViewManager?.updateApiUrl({
|
|
286
|
+
googleFitLastSync,
|
|
287
|
+
gfHourlyLastSync,
|
|
288
|
+
});
|
|
289
|
+
setHasLoadedOnce(true);
|
|
290
|
+
}
|
|
291
|
+
break;
|
|
292
|
+
|
|
293
|
+
case 'OPEN_PDF':
|
|
294
|
+
Linking.openURL(url);
|
|
295
|
+
break;
|
|
296
|
+
case 'CLOSE_VIEW':
|
|
297
|
+
break;
|
|
298
|
+
case 'GET_LOCATION_PERMISSIONS':
|
|
299
|
+
webviewRef.current?.injectJavaScript(
|
|
300
|
+
'window.checkTheGpsPermission(true)'
|
|
301
|
+
);
|
|
302
|
+
break;
|
|
303
|
+
|
|
304
|
+
default:
|
|
305
|
+
break;
|
|
306
|
+
}
|
|
307
|
+
};
|
|
308
|
+
|
|
309
|
+
const { height, width } = Dimensions.get('screen');
|
|
310
|
+
return (
|
|
311
|
+
// eslint-disable-next-line react-native/no-inline-styles
|
|
312
|
+
<SafeAreaView style={{ flex: 1, backgroundColor: 'white', height, width }}>
|
|
313
|
+
{loading ? (
|
|
314
|
+
<LoadingIndicator />
|
|
315
|
+
) : (
|
|
316
|
+
<WebView
|
|
317
|
+
ref={webviewRef}
|
|
318
|
+
source={{ uri: source }}
|
|
319
|
+
style={styles.webView}
|
|
320
|
+
javascriptEnabled
|
|
321
|
+
onMessage={handleMessage}
|
|
322
|
+
onError={(errorMessage) => {
|
|
323
|
+
EventRegister.emitEvent(visitEvent, {
|
|
324
|
+
message: 'web-view-error',
|
|
325
|
+
errorMessage: errorMessage,
|
|
326
|
+
});
|
|
327
|
+
if (isLoggingEnabled) {
|
|
328
|
+
console.warn('Webview error: ', errorMessage);
|
|
329
|
+
}
|
|
330
|
+
}}
|
|
331
|
+
/>
|
|
332
|
+
)}
|
|
333
|
+
</SafeAreaView>
|
|
334
|
+
);
|
|
335
|
+
};
|
|
336
|
+
|
|
337
|
+
const styles = StyleSheet.create({
|
|
338
|
+
webViewContainer: {
|
|
339
|
+
flex: 1,
|
|
340
|
+
backgroundColor: 'white',
|
|
341
|
+
},
|
|
342
|
+
webView: {
|
|
343
|
+
flex: 1,
|
|
344
|
+
},
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
MyTatvaRnSdkView.defaultProps = {
|
|
348
|
+
id: '',
|
|
349
|
+
token: '',
|
|
350
|
+
baseUrl: '',
|
|
351
|
+
errorBaseUrl: '',
|
|
352
|
+
moduleName: '',
|
|
353
|
+
};
|
|
354
|
+
|
|
355
|
+
export default MyTatvaRnSdkView;
|
|
356
|
+
|
|
357
|
+
const LoadingIndicator = () => {
|
|
358
|
+
return (
|
|
359
|
+
<ActivityIndicator
|
|
360
|
+
color="#000"
|
|
361
|
+
size="small"
|
|
362
|
+
// eslint-disable-next-line react-native/no-inline-styles
|
|
363
|
+
style={{
|
|
364
|
+
flex: 1,
|
|
365
|
+
zIndex: 100,
|
|
366
|
+
position: 'absolute',
|
|
367
|
+
backgroundColor: '#fff',
|
|
368
|
+
opacity: 0.4,
|
|
369
|
+
width: '100%',
|
|
370
|
+
height: '100%',
|
|
371
|
+
justifyContent: 'center',
|
|
372
|
+
alignItems: 'center',
|
|
373
|
+
}}
|
|
374
|
+
/>
|
|
375
|
+
);
|
|
376
|
+
};
|