shakebug-react-native 2.1.0 → 2.2.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.
Files changed (44) hide show
  1. package/README.md +17 -1
  2. package/VideoPlayer/index.js +37 -23
  3. package/android/build.gradle +0 -1
  4. package/android/src/main/java/com/shakebug/CreateThumbnailModule.java +217 -0
  5. package/android/src/main/java/com/shakebug/NetInfoModule.java +1 -2
  6. package/android/src/main/java/com/shakebug/RNDeviceModule.java +1 -3
  7. package/android/src/main/java/com/shakebug/ShakebugPackage.java +10 -10
  8. package/android/src/main/java/com/shakebug/{Shakebug.java → ShakebugSensors.java} +16 -22
  9. package/ios/GetLocals/ShakebugSDKRNLocalize.h +1 -0
  10. package/ios/Thumbnaill/{VideoThumbnailManager.h → CreateThumbnail.h} +2 -1
  11. package/ios/Thumbnaill/CreateThumbnail.m +82 -0
  12. package/package.json +2 -5
  13. package/shakebug-react-native.podspec +0 -1
  14. package/src/APIs/AddIssue.js +13 -4
  15. package/src/APIs/AddReview.js +46 -0
  16. package/src/APIs/CustomUserId.js +47 -0
  17. package/src/APIs/Event.js +8 -3
  18. package/src/APIs/StartSession.js +6 -2
  19. package/src/Assets/images/solar_star-bold.png +0 -0
  20. package/src/Assets/images/solar_star-line-duotone.png +0 -0
  21. package/src/Componanats/ReviewModal.js +171 -0
  22. package/src/Componanats/ShakeFunction.js +6 -3
  23. package/src/Screens/AddDetailsScreen.js +14 -10
  24. package/src/Screens/FirstScreen.js +2 -2
  25. package/src/Screens/Shakebug.js +63 -6
  26. package/src/Screens/TrimVideoScreen.js +13 -7
  27. package/src/index.tsx +6 -2
  28. package/android/src/main/java/com/shakebug/ShakebugSDKScreenShotModule.java +0 -196
  29. package/android/src/main/java/com/shakebug/VideoPlayerModule.java +0 -199
  30. package/android/src/main/java/com/shakebug/VideoThumbnailModule.java +0 -215
  31. package/android/src/main/java/com/shakebug/VideoTrimModule.java +0 -372
  32. package/android/src/main/java/com/shakebug/adapters/VideoTrimmerAdapter.java +0 -54
  33. package/android/src/main/java/com/shakebug/utils/StorageUtil.java +0 -139
  34. package/android/src/main/java/com/shakebug/utils/VideoTrimmerUtil.java +0 -89
  35. package/android/src/main/java/com/shakebug/widgets/RangeSeekBarView.java +0 -534
  36. package/android/src/main/java/com/shakebug/widgets/VideoPlayerView.java +0 -429
  37. package/android/src/main/java/com/shakebug/widgets/VideoTrimmerView.java +0 -477
  38. package/ios/Thumbnaill/VideoThumbnailManager.m +0 -73
  39. package/ios/TrimVideo/ShakebugSDKVideoTrim.swift +0 -372
  40. package/ios/TrimVideo/VideoTrim-Bridging-Header.h +0 -10
  41. package/ios/TrimVideo/VideoTrim.m +0 -23
  42. package/ios/TrimVideo/VideoTrimmer.swift +0 -810
  43. package/ios/TrimVideo/VideoTrimmerThumb.swift +0 -119
  44. package/ios/TrimVideo/VideoTrimmerViewController.swift +0 -301
@@ -1,3 +1,4 @@
1
+ import { NativeModules, Platform } from "react-native";
1
2
  import DeviceInfo from "../../DeviceInfo";
2
3
  import NetInfo from "../../NetInfo/src";
3
4
 
@@ -6,10 +7,15 @@ const API_KEY = global.ShakebugSDKEndPointURLheaderKey;
6
7
 
7
8
  async function AddIssueApi(session_id, application_id, path, isVideo, desc, email) {
8
9
  try {
10
+
11
+ const { ShakebugSDKSharedPreferencesModule } = NativeModules;
12
+
13
+ const Custom_User_Id = await ShakebugSDKSharedPreferencesModule.getString('custom_user_id')
14
+
9
15
  let i = 0;
10
16
  let internetType = "";
11
17
  NetInfo.addEventListener(stat => {
12
- if(i == 0){
18
+ if (i == 0) {
13
19
  internetType = stat.type
14
20
  }
15
21
  i++
@@ -25,9 +31,9 @@ async function AddIssueApi(session_id, application_id, path, isVideo, desc, emai
25
31
  let osversion = await DeviceInfo.getSystemVersion()
26
32
  const type = isVideo ? 'video/mp4' : 'image/png';
27
33
  const name = isVideo ? 'video' : 'photo.png';
28
- const media = isVideo ? `file://'${path}` : path;
29
-
30
-
34
+ const media = isVideo ? `file://'${path}` : path;
35
+
36
+
31
37
  const formData = new FormData();
32
38
  formData.append("method", "addIssue");
33
39
  formData.append("description", desc);
@@ -44,6 +50,9 @@ async function AddIssueApi(session_id, application_id, path, isVideo, desc, emai
44
50
  formData.append("created", created);
45
51
  formData.append("isVideo", isVideo);
46
52
  formData.append("appversion", appversion);
53
+ formData.append("custom_user_id", Custom_User_Id || "")
54
+ formData.append("sdk_version", global.sdk_version)
55
+ formData.append("platform", Platform.OS)
47
56
 
48
57
 
49
58
  const response = await fetch(BASE_URL, {
@@ -0,0 +1,46 @@
1
+ import { NativeModules } from "react-native";
2
+
3
+ const BASE_URL = global.ShakebugSDKEndPointURL;
4
+ const API_KEY = global.ShakebugSDKEndPointURLheaderKey;
5
+
6
+ async function AddReviewApi(rating, review, applicationsid, session_id) {
7
+
8
+ const { ShakebugSDKSharedPreferencesModule } = NativeModules;
9
+
10
+ const Custom_User_Id = await ShakebugSDKSharedPreferencesModule.getString('custom_user_id')
11
+
12
+ try {
13
+ const formData = new FormData();
14
+ formData.append("method", "addAppReview");
15
+ formData.append("applicationsid", applicationsid);
16
+ formData.append("rating", rating);
17
+ formData.append("review", review?.trim());
18
+ formData.append("session_id", session_id);
19
+ formData.append("appVersion", global.sdk_version);
20
+ formData.append("custom_user_id", Custom_User_Id);
21
+
22
+ const response = await fetch(BASE_URL, {
23
+ method: 'POST',
24
+ headers: {
25
+ 'API-KEY': API_KEY
26
+ },
27
+ body: formData,
28
+ });
29
+
30
+ const data = await response.json();
31
+
32
+ if (data.code === 200 && data.success === true) {
33
+ global.KEY_REVIEW_SUBMITTED = true;
34
+ return { success: true, message: data.msg };
35
+ } else {
36
+
37
+
38
+ return { success: false, message: data.msg };
39
+ }
40
+ } catch (error) {
41
+ // console.error('Error fetching data:', error);
42
+ throw error;
43
+ }
44
+ }
45
+
46
+ export { AddReviewApi };
@@ -0,0 +1,47 @@
1
+ import { NativeModules } from "react-native";
2
+
3
+ const BASE_URL = global.ShakebugSDKEndPointURL;
4
+ const API_KEY = global.ShakebugSDKEndPointURLheaderKey;
5
+
6
+ async function CustomUserIdApi(id, name, email, country, other, applicationsid) {
7
+
8
+ const { ShakebugSDKSharedPreferencesModule } = NativeModules;
9
+
10
+ try {
11
+ const formData = new FormData();
12
+ formData.append("method", "addCustomUserIds");
13
+ formData.append("id", id);
14
+ formData.append("name", name?.trim());
15
+ formData.append("email", email?.trim());
16
+ formData.append("country", country?.trim());
17
+ formData.append("other", other);
18
+ formData.append("applicationsid", applicationsid);
19
+
20
+ const response = await fetch(BASE_URL, {
21
+ method: 'POST',
22
+ headers: {
23
+ 'API-KEY': API_KEY
24
+ },
25
+ body: formData,
26
+ });
27
+
28
+ const data = await response.json();
29
+
30
+ if (data.code === 200 && data.success === true) {
31
+
32
+ ShakebugSDKSharedPreferencesModule.setString("custom_user_id", data?.response_data?.custom_user_id)
33
+
34
+ return { success: true, message: data.msg, data: data?.response_data?.custom_user_id };
35
+ } else {
36
+
37
+ ShakebugSDKSharedPreferencesModule.setString("custom_user_id", "")
38
+
39
+ return { success: false, message: data.msg, data: "" };
40
+ }
41
+ } catch (error) {
42
+ // console.error('Error fetching data:', error);
43
+ throw error;
44
+ }
45
+ }
46
+
47
+ export { CustomUserIdApi };
package/src/APIs/Event.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { NativeModules } from "react-native";
1
2
  import DeviceInfo from "../../DeviceInfo";
2
3
  import NetInfo from "../../NetInfo/src";
3
4
 
@@ -7,13 +8,17 @@ const API_KEY = global.ShakebugSDKEndPointURLheaderKey;
7
8
  async function EventApi(application_id, name, value) {
8
9
  try {
9
10
 
10
-
11
-
11
+ const { ShakebugSDKSharedPreferencesModule } = NativeModules;
12
+
13
+ const Custom_User_Id = await ShakebugSDKSharedPreferencesModule.getString('custom_user_id')
14
+
12
15
  const formData = new FormData();
13
16
  formData.append("method", "event");
14
17
  formData.append("applicationsid", application_id);
15
18
  formData.append("name", name);
16
19
  formData.append("value", value);
20
+ formData.append("custom_user_id", Custom_User_Id || "")
21
+ formData.append("sdk_version", global.sdk_version)
17
22
 
18
23
  const response = await fetch(BASE_URL, {
19
24
  method: 'POST',
@@ -24,7 +29,7 @@ async function EventApi(application_id, name, value) {
24
29
  });
25
30
 
26
31
  const data = await response.json();
27
-
32
+
28
33
  if (data.code === 200 && data.success === true) {
29
34
  return { success: true, message: data.msg };
30
35
  } else {
@@ -34,6 +34,8 @@ async function SessionStartApi(latitude, longitude, application_id) {
34
34
  let uuid = null;
35
35
  let idFromStorege = await ShakebugSDKSharedPreferencesModule.getString("uuid");
36
36
 
37
+ const Custom_User_Id = await ShakebugSDKSharedPreferencesModule.getString('custom_user_id')
38
+
37
39
  if (idFromStorege == "" || idFromStorege == undefined) {
38
40
  let id = await DeviceInfo.getUniqueId();
39
41
  ShakebugSDKSharedPreferencesModule.setString("uuid", id)
@@ -48,7 +50,7 @@ async function SessionStartApi(latitude, longitude, application_id) {
48
50
  let app_version = await DeviceInfo.getVersion()
49
51
 
50
52
  let device_name = await DeviceInfo.getDeviceName()
51
-
53
+
52
54
  let os = await DeviceInfo.getSystemName()
53
55
 
54
56
  let phone_carrier = await DeviceInfo.getCarrier()
@@ -71,7 +73,9 @@ async function SessionStartApi(latitude, longitude, application_id) {
71
73
  formData.append("longitude", longitude)
72
74
  formData.append("phonecarrier", phone_carrier)
73
75
  formData.append("appversion", app_version)
74
-
76
+ formData.append("custom_user_id", Custom_User_Id || "")
77
+ formData.append("sdk_version", global.sdk_version)
78
+
75
79
  try {
76
80
  const response = await fetch(BASE_URL, {
77
81
  method: 'POST',
@@ -0,0 +1,171 @@
1
+ import React, { useState } from 'react';
2
+ import { Modal, View, Text, TextInput, TouchableOpacity, StyleSheet, Image, KeyboardAvoidingView, ScrollView, TouchableWithoutFeedback, Keyboard, NativeModules } from 'react-native';
3
+ import { AddReviewApi } from 'shakebug-react-native/src/APIs/AddReview';
4
+
5
+ const ReviewModal = ({ visible, onClose, onSubmit, color }) => {
6
+
7
+ const { ShakebugSDKSharedPreferencesModule } = NativeModules;
8
+
9
+ const [rating, setRating] = useState(0);
10
+ const [feedback, setFeedback] = useState('');
11
+
12
+ const handleRating = (star) => setRating(star);
13
+
14
+ const handleSubmit = () => {
15
+ ShakebugSDKSharedPreferencesModule.setString("IS_REVIEW_SUBMITTED", "true");
16
+ AddReviewApi(rating, feedback, global.application_id, global.session_id);
17
+ setRating(0);
18
+ setFeedback('');
19
+ onClose();
20
+ };
21
+
22
+ return (
23
+ <Modal visible={visible} transparent animationType="fade">
24
+ <KeyboardAvoidingView
25
+ behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
26
+ style={styles.overlay}
27
+ keyboardVerticalOffset={Platform.OS === 'ios' ? 60 : 0}
28
+ >
29
+ <TouchableWithoutFeedback style={{ flex: 1 }} onPress={() => Keyboard.dismiss()}>
30
+ <ScrollView
31
+ contentContainerStyle={styles.scrollContainer}
32
+ keyboardShouldPersistTaps="handled"
33
+ bounces={false}
34
+ >
35
+ <View style={styles.modalContainer}>
36
+ <Text style={styles.title}>Rate Your Experience</Text>
37
+ <Text style={styles.subtitle}>We value your feedback</Text>
38
+
39
+ <View style={styles.starsContainer}>
40
+ {[1, 2, 3, 4, 5].map((star) => (
41
+ <TouchableOpacity key={star} onPress={() => handleRating(star)}>
42
+ <Image
43
+ source={
44
+ star <= rating
45
+ ? require("../Assets/images/solar_star-bold.png")
46
+ : require("../Assets/images/solar_star-line-duotone.png")
47
+ }
48
+ tintColor={color}
49
+ style={styles.star}
50
+ />
51
+ </TouchableOpacity>
52
+ ))}
53
+ </View>
54
+
55
+ <TextInput
56
+ placeholder="Write your review(optioanl)..."
57
+ placeholderTextColor="#999"
58
+ value={feedback}
59
+ onChangeText={setFeedback}
60
+ multiline
61
+ style={styles.textInput}
62
+ />
63
+
64
+ <View style={styles.buttons}>
65
+ <TouchableOpacity
66
+ style={styles.cancelButton}
67
+ onPress={() => {
68
+ ShakebugSDKSharedPreferencesModule.setString("LAST_POPUP_TIME", Date.now()?.toString())
69
+ onClose()
70
+ }}
71
+ >
72
+ <Text style={styles.cancelText}>Cancel</Text>
73
+ </TouchableOpacity>
74
+ <TouchableOpacity style={[styles.submitButton, { backgroundColor: color }]} onPress={handleSubmit}>
75
+ <Text style={styles.submitText}>Submit</Text>
76
+ </TouchableOpacity>
77
+ </View>
78
+ </View>
79
+ </ScrollView>
80
+ </TouchableWithoutFeedback>
81
+ </KeyboardAvoidingView>
82
+ </Modal>
83
+
84
+ );
85
+ };
86
+
87
+ export default ReviewModal;
88
+
89
+ const styles = StyleSheet.create({
90
+ overlay: {
91
+ flex: 1,
92
+ backgroundColor: '#00000066',
93
+ justifyContent: 'center',
94
+ alignItems: 'center',
95
+ },
96
+ scrollContainer: {
97
+ width: "100%",
98
+ height: "100%",
99
+ justifyContent: 'center',
100
+ alignItems: 'center',
101
+ },
102
+ modalContainer: {
103
+ width: '85%',
104
+ backgroundColor: '#fff',
105
+ borderRadius: 16,
106
+ padding: 20,
107
+ shadowColor: '#000',
108
+ shadowOpacity: 0.2,
109
+ shadowOffset: { width: 0, height: 4 },
110
+ shadowRadius: 10,
111
+ elevation: 8,
112
+ },
113
+ title: {
114
+ fontSize: 20,
115
+ fontWeight: '600',
116
+ marginBottom: 4,
117
+ textAlign: 'center',
118
+ color: '#333',
119
+ },
120
+ subtitle: {
121
+ fontSize: 14,
122
+ color: '#777',
123
+ marginBottom: 20,
124
+ textAlign: 'center',
125
+ },
126
+ starsContainer: {
127
+ flexDirection: 'row',
128
+ justifyContent: 'center',
129
+ marginBottom: 15,
130
+ },
131
+ star: {
132
+ width: 35,
133
+ height: 35,
134
+ marginHorizontal: 6,
135
+ },
136
+ textInput: {
137
+ borderColor: '#ccc',
138
+ borderWidth: 1,
139
+ borderRadius: 12,
140
+ padding: 10,
141
+ minHeight: 80,
142
+ textAlignVertical: 'top',
143
+ fontSize: 14,
144
+ color: '#333',
145
+ marginBottom: 20,
146
+ marginTop: 10
147
+ },
148
+ buttons: {
149
+ flexDirection: 'row',
150
+ alignItems: 'center',
151
+ justifyContent: 'flex-end',
152
+ },
153
+ cancelButton: {
154
+ marginRight: 12,
155
+ },
156
+ cancelText: {
157
+ fontSize: 16,
158
+ color: '#888',
159
+ },
160
+ submitButton: {
161
+ backgroundColor: '#007AFF',
162
+ borderRadius: 8,
163
+ paddingVertical: 8,
164
+ paddingHorizontal: 16,
165
+ },
166
+ submitText: {
167
+ color: '#fff',
168
+ fontWeight: '600',
169
+ fontSize: 16,
170
+ },
171
+ });
@@ -1,7 +1,7 @@
1
1
  import { View, Text, Platform, Image, ImageBackground, NativeModules, DeviceEventEmitter, NativeEventEmitter, StatusBar, PanResponder, Animated, AppState, Dimensions, BackHandler, LogBox, StyleSheet, SafeAreaView } from 'react-native'
2
2
  import React, { useRef, useEffect, useState } from 'react'
3
3
  import { SensorTypes, setUpdateIntervalForType, accelerometer } from '../../Sensor/src/index';
4
- import ViewShot from '../../ScreenShot/src/index';
4
+ import ViewShot from 'react-native-view-shot';
5
5
  import { TouchableOpacity } from 'react-native';
6
6
  import RecordScreen from '../../RecordScreen/src/index';
7
7
  import { ClearCanvas, RNDrawingView } from '../Screens/StrockView';
@@ -130,6 +130,7 @@ const ShakeFunction = ({ children, themeColor, showTutorialScreen, SDKScreenTitl
130
130
  useEffect(() => {
131
131
  async function fetchIsFirstTime() {
132
132
  iscrashSaveed = await ShakebugSDKSharedPreferencesModule.getString('iscrashSaveed')
133
+ const Custom_User_Id = await ShakebugSDKSharedPreferencesModule.getString('custom_user_id')
133
134
 
134
135
  if (iscrashSaveed.length > 10 && allowCrashReport) {
135
136
 
@@ -151,7 +152,8 @@ const ShakeFunction = ({ children, themeColor, showTutorialScreen, SDKScreenTitl
151
152
  formData.append("created", data["created"]);
152
153
  formData.append("isVideo", 0);
153
154
  formData.append("appversion", data["appversion"]);
154
-
155
+ formData.append("custom_user_id", Custom_User_Id || "")
156
+ formData.append("sdk_version", global.sdk_version)
155
157
 
156
158
 
157
159
  try {
@@ -321,13 +323,14 @@ const ShakeFunction = ({ children, themeColor, showTutorialScreen, SDKScreenTitl
321
323
  if (calculate.toFixed(2) >= 2.00) {
322
324
  if (global.isIOSValid == true && global.application_id != "" && global.application_id != undefined) {
323
325
  setIsScreenShot(true)
326
+
324
327
  let ImgUrl = await ref.current.capture()
325
328
  try {
326
329
  const filePath = await ShakebugSDKCustomScreenCapture.captureScreen();
327
330
  ImgUrl = filePath
328
331
  }
329
332
  catch (e) {
330
- console.log("e", e);
333
+
331
334
  }
332
335
  if (ImgUrl != undefined || ImgUrl != null) {
333
336
  subscription.unsubscribe();
@@ -21,8 +21,7 @@ LogBox.ignoreLogs([
21
21
  'Non-serializable values were found in the navigation state',
22
22
  ]);
23
23
 
24
- const { ShakebugSDKCreateThumbnail } = NativeModules;
25
-
24
+ const { CreateThumbnail } = NativeModules;
26
25
 
27
26
  const AddDetailsScreen = ({ media, updateParent, mediaType, themeColor, SDKScreenTitle }) => {
28
27
 
@@ -91,17 +90,23 @@ const AddDetailsScreen = ({ media, updateParent, mediaType, themeColor, SDKScree
91
90
  const generateThumbnail = async () => {
92
91
  if (type != "img") {
93
92
  try {
94
- const response = await ShakebugSDKCreateThumbnail.create({
93
+
94
+ const { create: createThumbnail } = CreateThumbnail;
95
+
96
+ const thumbnail = await createThumbnail({
95
97
  url: `file://${path}`,
96
98
  timeStamp: 10000,
97
- });
98
- if (response.path != "") {
99
- setPoster(response.path)
99
+ })
100
+
101
+ if (thumbnail) {
102
+ setPoster(thumbnail?.path)
100
103
  setIsLoading(false)
101
104
  }
102
105
  } catch (error) {
103
- throw new Error(error.message);
106
+ console.log(error);
107
+
104
108
  setIsLoading(false)
109
+ throw new Error(error.message);
105
110
  }
106
111
  }
107
112
  };
@@ -276,12 +281,11 @@ const AddDetailsScreen = ({ media, updateParent, mediaType, themeColor, SDKScree
276
281
  }
277
282
 
278
283
  UpdateStatusBar = () => {
279
- console.log("here");
280
284
  StatusBar.setHidden(false)
281
285
  }
282
286
 
283
287
  return (
284
- <SafeAreaView style={{ width: "100%", height: Dimensions.get('window').height, backgroundColor: themeColor, marginTop: Platform.OS == 'ios' ? StatusBar.currentHeight : 0, paddingBottom: 0 }}>
288
+ <SafeAreaView style={{ width: "100%", height: "100%", backgroundColor: themeColor, marginTop: Platform.OS == 'ios' ? StatusBar.currentHeight : 0, paddingBottom: 0 }}>
285
289
  <StatusBar backgroundColor={ThemeColor} hidden={false} />
286
290
  <KeyboardAvoidingWrapper>
287
291
  <>
@@ -418,7 +422,7 @@ const AddDetailsScreen = ({ media, updateParent, mediaType, themeColor, SDKScree
418
422
  </View>
419
423
 
420
424
  <View style={{ alignItems: 'flex-end', marginHorizontal: 15, marginTop: '1%' }}>
421
- <Text style={{ fontSize: 12, color: "gray", fontWeight: '300' }}>© <Text>ShakeBug v2.1</Text></Text>
425
+ <Text style={{ fontSize: 12, color: "gray", fontWeight: '300' }}>© <Text>ShakeBug v{global.sdk_version}</Text></Text>
422
426
  </View>
423
427
 
424
428
  </View>
@@ -1,7 +1,7 @@
1
1
  import { Alert, Image, ImageBackground, Linking, PermissionsAndroid, Platform, SafeAreaView, StatusBar, Text, TouchableOpacity, View, TextInput, Keyboard, PanResponder, Animated, StyleSheet, KeyboardAvoidingView, BackHandler, Dimensions, Modal } from 'react-native'
2
2
  import React, { useEffect, useRef, useState } from 'react'
3
3
  import { ClearCanvas, RNDrawingView } from './StrockView.js';
4
- import ViewShot from '../../ScreenShot/src/index.js';
4
+ import ViewShot from 'react-native-view-shot';
5
5
  import { launchImageLibrary } from '../../ImageOrVedioPicker/src/index';
6
6
  import { logger, consoleTransport } from "react-native-logs";
7
7
  import { NativeModules } from 'react-native';
@@ -310,7 +310,7 @@ const FirstScreen = ({ img, themeColor, SDKScreenTitle }) => {
310
310
  // backgroundColor: "#181818"
311
311
 
312
312
  return (
313
- <SafeAreaView style={{ width: "100%", height: Dimensions.get('window').height, backgroundColor: themeColor, marginTop: Platform.OS == 'ios' ? StatusBar.currentHeight : 0}}>
313
+ <SafeAreaView style={{ width: "100%", height: '100%', backgroundColor: themeColor, marginTop: Platform.OS == 'ios' ? StatusBar.currentHeight : 0}}>
314
314
  <StatusBar backgroundColor={ThemeColor} />
315
315
 
316
316
  <View style={{ width: "100%", height: "100%", backgroundColor: "#e4fdfd" }}>
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { Platform, Alert, AppState, NativeModules, View, StyleSheet, Animated, Dimensions, SafeAreaView } from 'react-native';
2
+ import { Platform, Alert, AppState, NativeModules, View, StyleSheet, Animated, Dimensions, SafeAreaView, Modal } from 'react-native';
3
3
  import ShakeFunction from '../Componanats/ShakeFunction';
4
4
  import FirstScreen from './FirstScreen';
5
5
  import AddDetailsScreen from './AddDetailsScreen';
@@ -19,6 +19,7 @@ import { NavigationProvider, useNavigation } from '../Componanats/NavigationCont
19
19
  import { Localization } from '../Componanats/localization';
20
20
  import { GlobalStateProvider, useGlobalState } from '../Componanats/GlobalStateContext';
21
21
  import CustomeAlert from 'shakebug-react-native/src/Componanats/CustomAlert';
22
+ import ReviewModal from 'shakebug-react-native/src/Componanats/ReviewModal';
22
23
 
23
24
  console.ignoredYellowBox = ["Warning: Each", "Warning: Failed"];
24
25
 
@@ -50,20 +51,27 @@ global.isScreeenShotTaken = false;
50
51
  global.restrictedViews = [];
51
52
  global.currentScreen = ""
52
53
  global.isShakebugSDKOpen = false;
54
+ global.sdk_version = "2.2.1";
55
+ global.app_lunch_count = 0;
56
+ global.POPUP_LAUNCH_THRESHOLD = 3;
57
+ global.POPUP_COOLDOWN_DAYS = 2;
58
+ global.KEY_REVIEW_SUBMITTED = false;
53
59
 
54
60
  function Shakebug({ children, Android_appkey, iOS_appkey, showTutorialScreenFirstTime, ShakebugThemeColor, changeSDKScreenTitle, allowToReportBugByShakingMobile, allowToReportBugByScreenCapture, allowCrashReport, ShakebugLanguage, makeLogEnabled, setShakebugSDKEndPointURL }) {
55
61
 
62
+ const { ShakebugSDKSharedPreferencesModule } = NativeModules;
63
+
56
64
  const ThemeColor = ShakebugThemeColor ? ShakebugThemeColor : "#1dd3e3";
57
65
  const FirstScreenTitle = changeSDKScreenTitle ? changeSDKScreenTitle[0] != "" ? changeSDKScreenTitle[0] : Localization[ShakebugLanguage].FirstScreenTitle : Localization[ShakebugLanguage].FirstScreenTitle;
58
66
  const SecondScreenTitle = changeSDKScreenTitle ? changeSDKScreenTitle[1] != "" ? changeSDKScreenTitle[1] : Localization[ShakebugLanguage].SecondScreenTitle : Localization[ShakebugLanguage].SecondScreenTitle;
59
67
  const [isAlert, setIsAlert] = useState(false)
60
68
  const [isAlertText, setAlertText] = useState("")
69
+ const [showModal, setShowModal] = useState(false);
61
70
  global.ShakebugLanguage = ShakebugLanguage;
62
71
  global.makeLogEnabled = makeLogEnabled;
63
- global.ShakebugSDKEndPointURL = setShakebugSDKEndPointURL[0].length > 0 ? setShakebugSDKEndPointURL[0] : "https://www.shakebug.com/api/v1.3/webservice.php/";
72
+ global.ShakebugSDKEndPointURL = setShakebugSDKEndPointURL[0].length > 0 ? setShakebugSDKEndPointURL[0] : "https://www.shakebug.com/api/v1.4/webservice.php/";
64
73
  global.ShakebugSDKEndPointURLheaderKey = setShakebugSDKEndPointURL[1].length > 0 ? setShakebugSDKEndPointURL[1] : "MarchShake2022";
65
74
 
66
- const { ShakebugSDKSharedPreferencesModule } = NativeModules;
67
75
 
68
76
  // DefaulfConfig for log
69
77
  const defaultConfig = {
@@ -114,6 +122,49 @@ function Shakebug({ children, Android_appkey, iOS_appkey, showTutorialScreenFirs
114
122
  // For check mau limit, valid appkey and call MatchKeyFunc
115
123
  useEffect(() => {
116
124
  async function fetchData() {
125
+
126
+ const KEY_APP_LAUNCH_COUNT = await ShakebugSDKSharedPreferencesModule.getString("KEY_APP_LAUNCH_COUNT") ? parseInt(await ShakebugSDKSharedPreferencesModule.getString("KEY_APP_LAUNCH_COUNT")) : 0;
127
+ const LAST_POPUP_TIME = await ShakebugSDKSharedPreferencesModule.getString("LAST_POPUP_TIME") ? parseInt(await ShakebugSDKSharedPreferencesModule.getString("LAST_POPUP_TIME")) : null;
128
+ const IS_REVIEW_SUBMITTED = await ShakebugSDKSharedPreferencesModule.getString("IS_REVIEW_SUBMITTED") || "false";
129
+
130
+ const SDK_VERSION = await ShakebugSDKSharedPreferencesModule.getString("SDK_VERSION")
131
+
132
+ ShakebugSDKSharedPreferencesModule.setString("KEY_APP_LAUNCH_COUNT", (KEY_APP_LAUNCH_COUNT + 1).toString())
133
+
134
+ if (SDK_VERSION) {
135
+ if (SDK_VERSION != global.sdk_version) {
136
+ ShakebugSDKSharedPreferencesModule.setString("KEY_APP_LAUNCH_COUNT", 0)
137
+ ShakebugSDKSharedPreferencesModule.setString("LAST_POPUP_TIME", null)
138
+ ShakebugSDKSharedPreferencesModule.setString("IS_REVIEW_SUBMITTED", "false")
139
+ ShakebugSDKSharedPreferencesModule.setString("SDK_VERSION", global.sdk_version)
140
+ }
141
+ }
142
+ else {
143
+ ShakebugSDKSharedPreferencesModule.setString("KEY_APP_LAUNCH_COUNT", 0)
144
+ ShakebugSDKSharedPreferencesModule.setString("LAST_POPUP_TIME", null)
145
+ ShakebugSDKSharedPreferencesModule.setString("IS_REVIEW_SUBMITTED", "false")
146
+ ShakebugSDKSharedPreferencesModule.setString("SDK_VERSION", global.sdk_version)
147
+ }
148
+
149
+ global.app_lunch_count = (KEY_APP_LAUNCH_COUNT + 1);
150
+
151
+ if (global.app_lunch_count >= POPUP_LAUNCH_THRESHOLD) {
152
+ if (LAST_POPUP_TIME && IS_REVIEW_SUBMITTED != "true") {
153
+ const now = Date.now(); // current timestamp in milliseconds
154
+ const sevenDaysInMs = global.POPUP_COOLDOWN_DAYS * 24 * 60 * 60 * 1000; // 7 days in milliseconds
155
+
156
+ const afterDaysTimestamp = now + sevenDaysInMs;
157
+
158
+ if (LAST_POPUP_TIME > afterDaysTimestamp) {
159
+ setShowModal(true)
160
+ }
161
+
162
+ }
163
+ else if (IS_REVIEW_SUBMITTED != "true") {
164
+ setShowModal(true)
165
+ }
166
+ }
167
+
117
168
  if (Android_appkey != undefined || iOS_appkey != undefined) {
118
169
  if (Platform.OS == 'android') {
119
170
  if (Android_appkey.trim().length > 0) {
@@ -172,10 +223,14 @@ function Shakebug({ children, Android_appkey, iOS_appkey, showTutorialScreenFirs
172
223
  }
173
224
  else {
174
225
  if (Platform.OS == 'android') {
175
- console.log("Please provide Android_appkey");
226
+ log.debug("------------------------------------------------------------------------------------------")
227
+ log.warn("Please provide Android_appkey");
228
+ log.debug("------------------------------------------------------------------------------------------")
176
229
  }
177
230
  else if (Platform.OS == 'ios') {
178
- console.log("Please provide iOS_appkey");
231
+ log.debug("------------------------------------------------------------------------------------------")
232
+ log.warn("Please provide iOS_appkey");
233
+ log.debug("------------------------------------------------------------------------------------------")
179
234
  }
180
235
  }
181
236
  }
@@ -407,7 +462,7 @@ function Shakebug({ children, Android_appkey, iOS_appkey, showTutorialScreenFirs
407
462
  </NavigationProvider>
408
463
  </GlobalStateProvider>
409
464
 
410
- <CustomeAlert
465
+ <CustomeAlert
411
466
  isVisible={isAlert}
412
467
  text={isAlertText}
413
468
  color={ThemeColor}
@@ -416,6 +471,8 @@ function Shakebug({ children, Android_appkey, iOS_appkey, showTutorialScreenFirs
416
471
  setIsAlert(false)
417
472
  }}
418
473
  />
474
+
475
+ <ReviewModal color={ThemeColor} visible={showModal} onClose={() => { setShowModal(false) }} />
419
476
  </View>
420
477
  )
421
478
  }