shakebug-react-native 2.4.13 → 2.4.14
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
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "shakebug-react-native",
|
|
3
3
|
"title": "shakebug-react-native",
|
|
4
|
-
"version": "2.4.
|
|
4
|
+
"version": "2.4.14",
|
|
5
5
|
"description": "Shakebug allows users to report the bug from your mobile phone for your application. Here users just need to shake their mobile and all the data regarding bugs & crashes can be seen by developers through their log in panel easily",
|
|
6
6
|
"main": "src/index.tsx",
|
|
7
7
|
"types": "src/index.tsx",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { View, Text, Button, StyleSheet, Modal, TouchableOpacity } from 'react-native';
|
|
3
3
|
|
|
4
|
-
const CustomeAlert = ({color, isVisible, OnPrees, text}) => {
|
|
4
|
+
const CustomeAlert = ({color, isVisible, OnPrees, text = ""}) => {
|
|
5
5
|
|
|
6
6
|
return (
|
|
7
7
|
<Modal
|
|
@@ -13,7 +13,7 @@ const CustomeAlert = ({color, isVisible, OnPrees, text}) => {
|
|
|
13
13
|
<View
|
|
14
14
|
style={[
|
|
15
15
|
styles.container, {
|
|
16
|
-
height: text.length > 120 ? 300 : text.length < 50 ? 170 : 200
|
|
16
|
+
height: (text && text.length > 120) ? 300 : (text && text.length < 50) ? 170 : 200
|
|
17
17
|
}]}
|
|
18
18
|
>
|
|
19
19
|
<Text style={styles.text}>
|
|
@@ -13,7 +13,7 @@ const ReviewModal = ({ visible, onClose, onSubmit, color }) => {
|
|
|
13
13
|
|
|
14
14
|
const handleSubmit = () => {
|
|
15
15
|
ShakebugSDKSharedPreferencesModule.setString("IS_REVIEW_SUBMITTED", "true");
|
|
16
|
-
AddReviewApi(rating, feedback, global.application_id, global.session_id);
|
|
16
|
+
AddReviewApi(rating, feedback, global.application_id, global.session_id).catch(() => {});
|
|
17
17
|
setRating(0);
|
|
18
18
|
setFeedback('');
|
|
19
19
|
onClose();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export const Localization = {
|
|
2
2
|
"ENGLISH": {
|
|
3
|
-
InterNetConnetionError: "Please check
|
|
3
|
+
InterNetConnetionError: "Please check your internet connection",
|
|
4
4
|
FirstScreenTitle: "Annotate your bug",
|
|
5
5
|
SecondScreenTitle: "Add Details",
|
|
6
6
|
RecordVideo: "Record Video?",
|
|
@@ -49,7 +49,7 @@ const AddDetailsScreen = ({ media, updateParent, mediaType, themeColor, SDKScree
|
|
|
49
49
|
// For handel system back navigation
|
|
50
50
|
useEffect(() => {
|
|
51
51
|
|
|
52
|
-
NetInfo.addEventListener(stat => {
|
|
52
|
+
const unsubscribeNetInfo = NetInfo.addEventListener(stat => {
|
|
53
53
|
setIsInternet(stat.isConnected)
|
|
54
54
|
})
|
|
55
55
|
|
|
@@ -73,7 +73,12 @@ const AddDetailsScreen = ({ media, updateParent, mediaType, themeColor, SDKScree
|
|
|
73
73
|
|
|
74
74
|
const backHandler = BackHandler.addEventListener('hardwareBackPress', backAction);
|
|
75
75
|
|
|
76
|
-
return () =>
|
|
76
|
+
return () => {
|
|
77
|
+
backHandler.remove();
|
|
78
|
+
if (unsubscribeNetInfo) {
|
|
79
|
+
unsubscribeNetInfo();
|
|
80
|
+
}
|
|
81
|
+
}; // Clean up the event listener on unmount
|
|
77
82
|
}, []);
|
|
78
83
|
|
|
79
84
|
|
package/src/Screens/Shakebug.js
CHANGED
|
@@ -16,7 +16,7 @@ import FirstScreen from './FirstScreen';
|
|
|
16
16
|
import AddDetailsScreen from './AddDetailsScreen';
|
|
17
17
|
import TrimVideoScreen from './TrimVideoScreen'
|
|
18
18
|
import DeviceInfo from '../../DeviceInfo';
|
|
19
|
-
import { useEffect, useState } from 'react';
|
|
19
|
+
import { useEffect, useState, useRef } from 'react';
|
|
20
20
|
import GetLocation from '../../GetLocation'
|
|
21
21
|
import NetInfo from '../../NetInfo/src'
|
|
22
22
|
import { SessionStartApi } from '../APIs/StartSession';
|
|
@@ -63,18 +63,18 @@ global.isScreeenShotTaken = false;
|
|
|
63
63
|
global.restrictedViews = [];
|
|
64
64
|
global.currentScreen = ""
|
|
65
65
|
global.isShakebugSDKOpen = false;
|
|
66
|
-
global.sdk_version = "2.4.
|
|
66
|
+
global.sdk_version = "2.4.14";
|
|
67
67
|
global.app_lunch_count = 0;
|
|
68
68
|
global.POPUP_LAUNCH_THRESHOLD = 3;
|
|
69
69
|
global.POPUP_COOLDOWN_DAYS = 2;
|
|
70
70
|
global.KEY_REVIEW_SUBMITTED = false;
|
|
71
|
-
// Initialize feature flags with defaults (allow
|
|
71
|
+
// Initialize feature flags with defaults (allow core reporting; reviews disabled by default until verified)
|
|
72
72
|
global.allowBugReport = true;
|
|
73
73
|
global.allowCrashReport = true;
|
|
74
74
|
global.allowEvent = true;
|
|
75
|
-
global.allowReview =
|
|
75
|
+
global.allowReview = false;
|
|
76
76
|
global.allowSession = true;
|
|
77
|
-
global.shakebug_type = "
|
|
77
|
+
global.shakebug_type = "";
|
|
78
78
|
global.sdk_platform = "react-native";
|
|
79
79
|
try {
|
|
80
80
|
global.sdk_platform_version = require("react-native/package.json").version;
|
|
@@ -190,27 +190,58 @@ const ShakeScreen = () => {
|
|
|
190
190
|
|
|
191
191
|
|
|
192
192
|
|
|
193
|
-
function Shakebug({
|
|
193
|
+
function Shakebug({
|
|
194
|
+
children,
|
|
195
|
+
Android_appkey,
|
|
196
|
+
iOS_appkey,
|
|
197
|
+
showTutorialScreenFirstTime = true,
|
|
198
|
+
ShakebugThemeColor = "#1dd3e3",
|
|
199
|
+
changeSDKScreenTitle = ['Annotate your bug', 'Add Details'],
|
|
200
|
+
allowToReportBugByShakingMobile = true,
|
|
201
|
+
allowToReportBugByScreenCapture = false,
|
|
202
|
+
allowCrashReport = true,
|
|
203
|
+
ShakebugLanguage = "ENGLISH",
|
|
204
|
+
makeLogEnabled = false,
|
|
205
|
+
setShakebugSDKEndPointURL = ["https://www.shakebug.com/api/v1.6/webservice.php/", "MarchShake2022", ""]
|
|
206
|
+
}) {
|
|
194
207
|
|
|
195
208
|
const [allowBugReport, setAllowBugReport] = useState(true);
|
|
196
209
|
const [allowCrashFlag, setAllowCrashFlag] = useState(true);
|
|
197
210
|
const [allowEventFlag, setAllowEventFlag] = useState(true);
|
|
198
|
-
const [allowReviewFlag, setAllowReviewFlag] = useState(
|
|
211
|
+
const [allowReviewFlag, setAllowReviewFlag] = useState(false);
|
|
199
212
|
const [allowSessionFlag, setAllowSessionFlag] = useState(true);
|
|
200
213
|
|
|
201
214
|
const { ShakebugSDKSharedPreferencesModule } = NativeModules;
|
|
202
215
|
|
|
216
|
+
const validLanguage = (ShakebugLanguage && Localization[ShakebugLanguage])
|
|
217
|
+
? ShakebugLanguage
|
|
218
|
+
: (global.ShakebugLanguage && Localization[global.ShakebugLanguage])
|
|
219
|
+
? global.ShakebugLanguage
|
|
220
|
+
: "ENGLISH";
|
|
221
|
+
global.ShakebugLanguage = validLanguage;
|
|
222
|
+
|
|
203
223
|
const ThemeColor = ShakebugThemeColor ? ShakebugThemeColor : "#1dd3e3";
|
|
204
|
-
const FirstScreenTitle = changeSDKScreenTitle
|
|
205
|
-
|
|
224
|
+
const FirstScreenTitle = (changeSDKScreenTitle && changeSDKScreenTitle[0] && changeSDKScreenTitle[0] !== "")
|
|
225
|
+
? changeSDKScreenTitle[0]
|
|
226
|
+
: Localization[validLanguage]?.FirstScreenTitle || "Annotate your bug";
|
|
227
|
+
const SecondScreenTitle = (changeSDKScreenTitle && changeSDKScreenTitle[1] && changeSDKScreenTitle[1] !== "")
|
|
228
|
+
? changeSDKScreenTitle[1]
|
|
229
|
+
: Localization[validLanguage]?.SecondScreenTitle || "Add Details";
|
|
206
230
|
const [isAlert, setIsAlert] = useState(false)
|
|
207
231
|
const [isAlertText, setAlertText] = useState("")
|
|
208
232
|
const [showModal, setShowModal] = useState(false);
|
|
209
233
|
const [focusedScreen, setFocusedScreen] = useState('');
|
|
210
|
-
global.ShakebugLanguage = ShakebugLanguage;
|
|
211
234
|
global.makeLogEnabled = makeLogEnabled;
|
|
212
|
-
global.ShakebugSDKEndPointURL = setShakebugSDKEndPointURL[0]
|
|
213
|
-
|
|
235
|
+
global.ShakebugSDKEndPointURL = (setShakebugSDKEndPointURL && setShakebugSDKEndPointURL[0] && setShakebugSDKEndPointURL[0].length > 0)
|
|
236
|
+
? setShakebugSDKEndPointURL[0]
|
|
237
|
+
: "https://www.shakebug.com/api/v1.6/webservice.php/";
|
|
238
|
+
global.ShakebugSDKEndPointURLheaderKey = (setShakebugSDKEndPointURL && setShakebugSDKEndPointURL[1] && setShakebugSDKEndPointURL[1].length > 0)
|
|
239
|
+
? setShakebugSDKEndPointURL[1]
|
|
240
|
+
: "MarchShake2022";
|
|
241
|
+
|
|
242
|
+
const connectionAlertShownRef = useRef(false);
|
|
243
|
+
const isMatchingKeyRef = useRef(false);
|
|
244
|
+
const reviewTimeoutRef = useRef(null);
|
|
214
245
|
|
|
215
246
|
|
|
216
247
|
// DefaulfConfig for log
|
|
@@ -259,116 +290,362 @@ function Shakebug({ children, Android_appkey, iOS_appkey, showTutorialScreenFirs
|
|
|
259
290
|
fetchData();
|
|
260
291
|
}, [Android_appkey, iOS_appkey])
|
|
261
292
|
|
|
262
|
-
// For
|
|
263
|
-
|
|
264
|
-
|
|
293
|
+
// For call Startsesstion and get session id
|
|
294
|
+
const StartSession = async () => {
|
|
295
|
+
if (global.session_id == "") {
|
|
296
|
+
try {
|
|
297
|
+
const { success, session_id: newSessionId, message } = await SessionStartApi(global.latitude, global.longitude, global.application_id);
|
|
298
|
+
if (success) {
|
|
299
|
+
global.session_id = newSessionId
|
|
300
|
+
log.debug("------------------------------------------------------------------------------------------")
|
|
301
|
+
log.info('API response:', message);
|
|
302
|
+
log.debug("------------------------------------------------------------------------------------------")
|
|
303
|
+
} else {
|
|
304
|
+
log.debug("------------------------------------------------------------------------------------------")
|
|
305
|
+
log.warn(message);
|
|
306
|
+
log.debug("------------------------------------------------------------------------------------------")
|
|
307
|
+
global.session_id = ""
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
catch (err) {
|
|
311
|
+
log.error("err", err)
|
|
312
|
+
}
|
|
313
|
+
}
|
|
265
314
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
315
|
+
DeviceInfo.isEmulator().then(res => {
|
|
316
|
+
if (res === true) {
|
|
317
|
+
log.info("Supports real device only");
|
|
318
|
+
}
|
|
319
|
+
})
|
|
320
|
+
}
|
|
269
321
|
|
|
270
|
-
|
|
322
|
+
// Set feature flags based on shakebug_type (supports comma‑separated codes)
|
|
323
|
+
const applyFeatureFlags = (type) => {
|
|
324
|
+
if (type === undefined || type === null || type === "") return;
|
|
325
|
+
|
|
326
|
+
// Reset all flags to false initially
|
|
327
|
+
global.allowBugReport = false;
|
|
328
|
+
global.allowCrashReport = false;
|
|
329
|
+
global.allowEvent = false;
|
|
330
|
+
global.allowReview = false;
|
|
331
|
+
global.allowSession = false;
|
|
332
|
+
|
|
333
|
+
// Helper to enable a specific flag
|
|
334
|
+
const enableFlag = (code) => {
|
|
335
|
+
switch (code) {
|
|
336
|
+
case "0":
|
|
337
|
+
// Disable all – already false
|
|
338
|
+
break;
|
|
339
|
+
case "1":
|
|
340
|
+
// Enable all
|
|
341
|
+
global.allowBugReport = true;
|
|
342
|
+
global.allowCrashReport = true;
|
|
343
|
+
global.allowEvent = true;
|
|
344
|
+
global.allowReview = true;
|
|
345
|
+
global.allowSession = true;
|
|
346
|
+
break;
|
|
347
|
+
case "2":
|
|
348
|
+
global.allowBugReport = true;
|
|
349
|
+
break;
|
|
350
|
+
case "3":
|
|
351
|
+
global.allowCrashReport = true;
|
|
352
|
+
break;
|
|
353
|
+
case "4":
|
|
354
|
+
global.allowEvent = true;
|
|
355
|
+
break;
|
|
356
|
+
case "5":
|
|
357
|
+
global.allowSession = true;
|
|
358
|
+
break;
|
|
359
|
+
case "6":
|
|
360
|
+
global.allowReview = true;
|
|
361
|
+
break;
|
|
362
|
+
default:
|
|
363
|
+
// ignore unknown codes
|
|
364
|
+
break;
|
|
365
|
+
}
|
|
366
|
+
};
|
|
271
367
|
|
|
272
|
-
|
|
368
|
+
// Split the incoming string and enable flags for each code
|
|
369
|
+
const codes = String(type).split(',').map(c => c.trim());
|
|
370
|
+
codes.forEach(enableFlag);
|
|
273
371
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
372
|
+
// Store raw type for reference
|
|
373
|
+
global.shakebug_type = type;
|
|
374
|
+
|
|
375
|
+
// Update React state so UI re‑renders with new flags
|
|
376
|
+
setAllowBugReport(global.allowBugReport);
|
|
377
|
+
setAllowCrashFlag(global.allowCrashReport);
|
|
378
|
+
setAllowEventFlag(global.allowEvent);
|
|
379
|
+
setAllowReviewFlag(global.allowReview);
|
|
380
|
+
setAllowSessionFlag(global.allowSession);
|
|
381
|
+
};
|
|
382
|
+
|
|
383
|
+
const checkAndScheduleReviewPopup = async () => {
|
|
384
|
+
try {
|
|
385
|
+
if (!global.allowReview || !global.application_id) {
|
|
386
|
+
return;
|
|
281
387
|
}
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
ShakebugSDKSharedPreferencesModule.
|
|
285
|
-
|
|
286
|
-
|
|
388
|
+
|
|
389
|
+
const LAST_POPUP_TIME = (await ShakebugSDKSharedPreferencesModule.getString("LAST_POPUP_TIME"))
|
|
390
|
+
? parseInt(await ShakebugSDKSharedPreferencesModule.getString("LAST_POPUP_TIME"))
|
|
391
|
+
: null;
|
|
392
|
+
const IS_REVIEW_SUBMITTED = (await ShakebugSDKSharedPreferencesModule.getString("IS_REVIEW_SUBMITTED")) || "false";
|
|
393
|
+
|
|
394
|
+
if (global.app_lunch_count >= global.POPUP_LAUNCH_THRESHOLD && global.allowReview) {
|
|
395
|
+
if (LAST_POPUP_TIME && LAST_POPUP_TIME != "" && IS_REVIEW_SUBMITTED != "true") {
|
|
396
|
+
const now = Date.now(); // current timestamp in milliseconds
|
|
397
|
+
const cooldownInMs = global.POPUP_COOLDOWN_DAYS * 24 * 60 * 60 * 1000;
|
|
398
|
+
|
|
399
|
+
if (now - parseInt(LAST_POPUP_TIME) >= cooldownInMs) {
|
|
400
|
+
if (reviewTimeoutRef.current) {
|
|
401
|
+
clearTimeout(reviewTimeoutRef.current);
|
|
402
|
+
}
|
|
403
|
+
reviewTimeoutRef.current = setTimeout(() => {
|
|
404
|
+
if (global.allowReview && global.application_id) {
|
|
405
|
+
setShowModal(true);
|
|
406
|
+
}
|
|
407
|
+
}, 15000);
|
|
408
|
+
}
|
|
409
|
+
} else if (IS_REVIEW_SUBMITTED != "true") {
|
|
410
|
+
if (reviewTimeoutRef.current) {
|
|
411
|
+
clearTimeout(reviewTimeoutRef.current);
|
|
412
|
+
}
|
|
413
|
+
reviewTimeoutRef.current = setTimeout(() => {
|
|
414
|
+
if (global.allowReview && global.application_id) {
|
|
415
|
+
setShowModal(true);
|
|
416
|
+
}
|
|
417
|
+
}, 15000);
|
|
418
|
+
}
|
|
287
419
|
}
|
|
420
|
+
} catch (err) {
|
|
421
|
+
log.error("Error scheduling review popup", err);
|
|
422
|
+
}
|
|
423
|
+
};
|
|
424
|
+
|
|
425
|
+
// For call Match key app and get application id
|
|
426
|
+
const MatchKeyFunc = async (appkey) => {
|
|
427
|
+
try {
|
|
428
|
+
let BundleId = DeviceInfo.getBundleId();
|
|
429
|
+
|
|
430
|
+
const { success, application_id: newApplication_id, message, total_mau, used_mau, total_video, used_video, video_duration, shakebug_type } = await MatchKeyApi(appkey, BundleId);
|
|
431
|
+
|
|
432
|
+
global.videoDuration = video_duration;
|
|
433
|
+
|
|
434
|
+
if (success) {
|
|
435
|
+
if (total_video == "Unlimited") {
|
|
436
|
+
global.AllowVideo = true;
|
|
437
|
+
}
|
|
438
|
+
else if (used_video == null) {
|
|
439
|
+
global.AllowVideo = true;
|
|
440
|
+
}
|
|
441
|
+
else if (parseInt(total_video) > parseInt(used_video)) {
|
|
442
|
+
global.AllowVideo = true;
|
|
443
|
+
}
|
|
444
|
+
else {
|
|
445
|
+
global.AllowVideo = false;
|
|
446
|
+
global.total_video = total_video;
|
|
447
|
+
global.used_video = used_video;
|
|
448
|
+
}
|
|
288
449
|
|
|
289
|
-
|
|
450
|
+
if (total_mau.toString() == used_mau.toString()) {
|
|
451
|
+
let date = new Date().getTime() + 6 * 60 * 60 * 1000
|
|
452
|
+
ShakebugSDKSharedPreferencesModule.setString("mauReachedTime", date.toString())
|
|
453
|
+
}
|
|
454
|
+
if (Platform.OS == "android") {
|
|
455
|
+
global.isAndroidValid = true
|
|
456
|
+
}
|
|
457
|
+
else {
|
|
458
|
+
global.isIOSValid = true
|
|
459
|
+
}
|
|
460
|
+
global.application_id = newApplication_id;
|
|
290
461
|
|
|
462
|
+
// Apply and persist feature flags
|
|
463
|
+
applyFeatureFlags(shakebug_type);
|
|
464
|
+
if (shakebug_type) {
|
|
465
|
+
ShakebugSDKSharedPreferencesModule.setString("SHAKEBUG_TYPE", String(shakebug_type));
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
log.debug("------------------------------------------------------------------------------------------");
|
|
469
|
+
log.info('API response:', message);
|
|
470
|
+
log.debug("------------------------------------------------------------------------------------------");
|
|
471
|
+
if (global.allowSession) { StartSession(); }
|
|
472
|
+
|
|
473
|
+
checkAndScheduleReviewPopup();
|
|
474
|
+
return true;
|
|
475
|
+
} else {
|
|
476
|
+
if (Platform.OS == "android") {
|
|
477
|
+
global.isAndroidValid = false
|
|
478
|
+
}
|
|
479
|
+
else {
|
|
480
|
+
global.isIOSValid = false
|
|
481
|
+
}
|
|
482
|
+
log.debug("------------------------------------------------------------------------------------------")
|
|
483
|
+
log.warn(message);
|
|
484
|
+
log.debug("------------------------------------------------------------------------------------------")
|
|
485
|
+
global.application_id = ""
|
|
486
|
+
return false;
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
catch (err) {
|
|
490
|
+
log.error("Err", err)
|
|
491
|
+
if (err === "Network request failed" || err?.message === "Network request failed") {
|
|
492
|
+
log.warn("Please check your internet connection")
|
|
493
|
+
}
|
|
494
|
+
return false;
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
const executeMatchKey = async () => {
|
|
499
|
+
if (global.application_id && global.application_id.trim().length > 0) {
|
|
500
|
+
return true;
|
|
501
|
+
}
|
|
502
|
+
if (isMatchingKeyRef.current) {
|
|
503
|
+
return false;
|
|
504
|
+
}
|
|
505
|
+
isMatchingKeyRef.current = true;
|
|
506
|
+
try {
|
|
291
507
|
if (Platform.OS == 'android') {
|
|
292
508
|
if (Android_appkey && Android_appkey.trim().length > 0) {
|
|
293
509
|
try {
|
|
294
510
|
const ismauReached = await ShakebugSDKSharedPreferencesModule.getString('mauReachedTime');
|
|
295
511
|
if (!ismauReached) {
|
|
296
|
-
await MatchKeyFunc(Android_appkey);
|
|
512
|
+
return await MatchKeyFunc(Android_appkey);
|
|
297
513
|
} else if (parseInt(ismauReached) < new Date().getTime()) {
|
|
298
|
-
await MatchKeyFunc(Android_appkey);
|
|
514
|
+
const res = await MatchKeyFunc(Android_appkey);
|
|
299
515
|
ShakebugSDKSharedPreferencesModule.setString("mauReachedTime", "");
|
|
516
|
+
return res;
|
|
300
517
|
} else {
|
|
301
518
|
log.debug("------------------------------------------------------------------------------------------");
|
|
302
519
|
log.warn('MAU limit is arrived, please try after', new Date(parseInt(ismauReached)).toLocaleString());
|
|
303
520
|
log.debug("------------------------------------------------------------------------------------------");
|
|
521
|
+
return false;
|
|
304
522
|
}
|
|
305
523
|
} catch (err) {
|
|
306
524
|
log.error("Err here", err);
|
|
525
|
+
return false;
|
|
307
526
|
}
|
|
308
527
|
} else {
|
|
309
528
|
log.warn("Please provide valid android appkey");
|
|
529
|
+
return false;
|
|
310
530
|
}
|
|
311
531
|
} else if (Platform.OS == 'ios') {
|
|
312
532
|
if (iOS_appkey && iOS_appkey.trim().length > 0) {
|
|
313
533
|
try {
|
|
314
534
|
const ismauReached = await ShakebugSDKSharedPreferencesModule.getString('mauReachedTime');
|
|
315
535
|
if (!ismauReached) {
|
|
316
|
-
await MatchKeyFunc(iOS_appkey);
|
|
536
|
+
return await MatchKeyFunc(iOS_appkey);
|
|
317
537
|
} else if (parseInt(ismauReached) < new Date().getTime()) {
|
|
318
|
-
await MatchKeyFunc(iOS_appkey);
|
|
538
|
+
const res = await MatchKeyFunc(iOS_appkey);
|
|
319
539
|
ShakebugSDKSharedPreferencesModule.setString("mauReachedTime", "");
|
|
540
|
+
return res;
|
|
320
541
|
} else {
|
|
321
542
|
log.debug("------------------------------------------------------------------------------------------");
|
|
322
543
|
log.warn('MAU limit is arrived, please try after', new Date(parseInt(ismauReached)).toLocaleString());
|
|
323
544
|
log.debug("------------------------------------------------------------------------------------------");
|
|
545
|
+
return false;
|
|
324
546
|
}
|
|
325
547
|
} catch (err) {
|
|
326
548
|
log.error("Err", err);
|
|
549
|
+
return false;
|
|
327
550
|
}
|
|
328
551
|
} else {
|
|
329
552
|
log.warn("Please provide valid ios appkey");
|
|
553
|
+
return false;
|
|
330
554
|
}
|
|
331
555
|
}
|
|
556
|
+
return false;
|
|
557
|
+
} finally {
|
|
558
|
+
isMatchingKeyRef.current = false;
|
|
559
|
+
}
|
|
560
|
+
};
|
|
332
561
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
const cooldownInMs = global.POPUP_COOLDOWN_DAYS * 24 * 60 * 60 * 1000;
|
|
562
|
+
// For check mau limit, valid appkey, handle connectivity, and call MatchKeyFunc
|
|
563
|
+
useEffect(() => {
|
|
564
|
+
let isMounted = true;
|
|
337
565
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
566
|
+
async function initLaunchData() {
|
|
567
|
+
try {
|
|
568
|
+
const KEY_APP_LAUNCH_COUNT = (await ShakebugSDKSharedPreferencesModule.getString("KEY_APP_LAUNCH_COUNT"))
|
|
569
|
+
? parseInt(await ShakebugSDKSharedPreferencesModule.getString("KEY_APP_LAUNCH_COUNT"))
|
|
570
|
+
: 0;
|
|
571
|
+
const SDK_VERSION = await ShakebugSDKSharedPreferencesModule.getString("SDK_VERSION");
|
|
572
|
+
|
|
573
|
+
if (SDK_VERSION) {
|
|
574
|
+
if (SDK_VERSION != global.sdk_version) {
|
|
575
|
+
await ShakebugSDKSharedPreferencesModule.setString("KEY_APP_LAUNCH_COUNT", "1");
|
|
576
|
+
await ShakebugSDKSharedPreferencesModule.setString("LAST_POPUP_TIME", "");
|
|
577
|
+
await ShakebugSDKSharedPreferencesModule.setString("IS_REVIEW_SUBMITTED", "false");
|
|
578
|
+
await ShakebugSDKSharedPreferencesModule.setString("SDK_VERSION", global.sdk_version);
|
|
579
|
+
global.app_lunch_count = 1;
|
|
580
|
+
} else {
|
|
581
|
+
const newCount = KEY_APP_LAUNCH_COUNT + 1;
|
|
582
|
+
await ShakebugSDKSharedPreferencesModule.setString("KEY_APP_LAUNCH_COUNT", newCount.toString());
|
|
583
|
+
global.app_lunch_count = newCount;
|
|
344
584
|
}
|
|
345
|
-
|
|
585
|
+
} else {
|
|
586
|
+
await ShakebugSDKSharedPreferencesModule.setString("KEY_APP_LAUNCH_COUNT", "1");
|
|
587
|
+
await ShakebugSDKSharedPreferencesModule.setString("LAST_POPUP_TIME", "");
|
|
588
|
+
await ShakebugSDKSharedPreferencesModule.setString("IS_REVIEW_SUBMITTED", "false");
|
|
589
|
+
await ShakebugSDKSharedPreferencesModule.setString("SDK_VERSION", global.sdk_version);
|
|
590
|
+
global.app_lunch_count = 1;
|
|
346
591
|
}
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
}, 15000);
|
|
592
|
+
|
|
593
|
+
// Load cached feature flags from previous session if available
|
|
594
|
+
const cachedShakebugType = await ShakebugSDKSharedPreferencesModule.getString("SHAKEBUG_TYPE");
|
|
595
|
+
if (cachedShakebugType && cachedShakebugType.trim().length > 0) {
|
|
596
|
+
applyFeatureFlags(cachedShakebugType);
|
|
353
597
|
}
|
|
598
|
+
} catch (err) {
|
|
599
|
+
log.error("Err initializing launch data", err);
|
|
354
600
|
}
|
|
355
601
|
}
|
|
356
602
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
603
|
+
initLaunchData();
|
|
604
|
+
|
|
605
|
+
const handleConnectivityChange = (state) => {
|
|
606
|
+
if (!isMounted || !state) return;
|
|
607
|
+
|
|
608
|
+
// Ignore unknown/null initial state until native connectivity is reported
|
|
609
|
+
if (state.isConnected === null) return;
|
|
610
|
+
|
|
611
|
+
const isConnected = state.isConnected === true;
|
|
612
|
+
const lang = (global.ShakebugLanguage && Localization[global.ShakebugLanguage])
|
|
613
|
+
? global.ShakebugLanguage
|
|
614
|
+
: "ENGLISH";
|
|
615
|
+
const errorMsg = Localization[lang]?.InterNetConnetionError || "Please check your internet connection";
|
|
616
|
+
|
|
617
|
+
if (!isConnected) {
|
|
618
|
+
setAlertText(errorMsg);
|
|
619
|
+
setIsAlert(true);
|
|
620
|
+
connectionAlertShownRef.current = true;
|
|
621
|
+
} else {
|
|
622
|
+
if (connectionAlertShownRef.current || isAlert) {
|
|
623
|
+
setIsAlert(false);
|
|
624
|
+
setAlertText("");
|
|
625
|
+
connectionAlertShownRef.current = false;
|
|
362
626
|
}
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
setIsAlert(true)
|
|
627
|
+
if (!global.application_id || global.application_id === "") {
|
|
628
|
+
executeMatchKey();
|
|
366
629
|
}
|
|
367
630
|
}
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
631
|
+
};
|
|
632
|
+
|
|
633
|
+
// Check immediate connectivity on mount
|
|
634
|
+
NetInfo.fetch().then(handleConnectivityChange).catch(() => {});
|
|
371
635
|
|
|
636
|
+
// Listen to network changes (online <-> offline)
|
|
637
|
+
const unsubscribe = NetInfo.addEventListener(handleConnectivityChange);
|
|
638
|
+
|
|
639
|
+
return () => {
|
|
640
|
+
isMounted = false;
|
|
641
|
+
if (unsubscribe) {
|
|
642
|
+
unsubscribe();
|
|
643
|
+
}
|
|
644
|
+
if (reviewTimeoutRef.current) {
|
|
645
|
+
clearTimeout(reviewTimeoutRef.current);
|
|
646
|
+
}
|
|
647
|
+
};
|
|
648
|
+
}, [Android_appkey, iOS_appkey]);
|
|
372
649
|
|
|
373
650
|
// For close or start session according app state
|
|
374
651
|
useEffect(() => {
|
|
@@ -416,150 +693,6 @@ function Shakebug({ children, Android_appkey, iOS_appkey, showTutorialScreenFirs
|
|
|
416
693
|
};
|
|
417
694
|
}, [global.IsBackground]);
|
|
418
695
|
|
|
419
|
-
|
|
420
|
-
// For call Match key app and get application id
|
|
421
|
-
const MatchKeyFunc = async (appkey) => {
|
|
422
|
-
try {
|
|
423
|
-
let BundleId = DeviceInfo.getBundleId();
|
|
424
|
-
|
|
425
|
-
const { success, application_id: newApplication_id, message, total_mau, used_mau, total_video, used_video, video_duration, shakebug_type } = await MatchKeyApi(appkey, BundleId);
|
|
426
|
-
|
|
427
|
-
global.videoDuration = video_duration;
|
|
428
|
-
|
|
429
|
-
if (success) {
|
|
430
|
-
if (total_video == "Unlimited") {
|
|
431
|
-
global.AllowVideo = true;
|
|
432
|
-
}
|
|
433
|
-
else if (used_video == null) {
|
|
434
|
-
global.AllowVideo = true;
|
|
435
|
-
}
|
|
436
|
-
else if (parseInt(total_video) > parseInt(used_video)) {
|
|
437
|
-
global.AllowVideo = true;
|
|
438
|
-
}
|
|
439
|
-
else {
|
|
440
|
-
global.AllowVideo = false;
|
|
441
|
-
global.total_video = total_video;
|
|
442
|
-
global.used_video = used_video;
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
if (total_mau.toString() == used_mau.toString()) {
|
|
446
|
-
let date = new Date().getTime() + 6 * 60 * 60 * 1000
|
|
447
|
-
ShakebugSDKSharedPreferencesModule.setString("mauReachedTime", date.toString())
|
|
448
|
-
}
|
|
449
|
-
if (Platform.OS == "android") {
|
|
450
|
-
global.isAndroidValid = true
|
|
451
|
-
}
|
|
452
|
-
else {
|
|
453
|
-
global.isIOSValid = true
|
|
454
|
-
}
|
|
455
|
-
global.application_id = newApplication_id;
|
|
456
|
-
// Set feature flags based on shakebug_type (supports comma‑separated codes)
|
|
457
|
-
// Reset all flags to false initially
|
|
458
|
-
global.allowBugReport = false;
|
|
459
|
-
global.allowCrashReport = false;
|
|
460
|
-
global.allowEvent = false;
|
|
461
|
-
global.allowReview = false;
|
|
462
|
-
global.allowSession = false;
|
|
463
|
-
// Helper to enable a specific flag
|
|
464
|
-
const enableFlag = (code) => {
|
|
465
|
-
switch (code) {
|
|
466
|
-
case "0":
|
|
467
|
-
// Disable all – already false
|
|
468
|
-
break;
|
|
469
|
-
case "1":
|
|
470
|
-
// Enable all
|
|
471
|
-
global.allowBugReport = true;
|
|
472
|
-
global.allowCrashReport = true;
|
|
473
|
-
global.allowEvent = true;
|
|
474
|
-
global.allowReview = true;
|
|
475
|
-
global.allowSession = true;
|
|
476
|
-
break;
|
|
477
|
-
case "2":
|
|
478
|
-
global.allowBugReport = true;
|
|
479
|
-
break;
|
|
480
|
-
case "3":
|
|
481
|
-
global.allowCrashReport = true;
|
|
482
|
-
break;
|
|
483
|
-
case "4":
|
|
484
|
-
global.allowEvent = true;
|
|
485
|
-
break;
|
|
486
|
-
case "5":
|
|
487
|
-
global.allowSession = true;
|
|
488
|
-
break;
|
|
489
|
-
case "6":
|
|
490
|
-
global.allowReview = true;
|
|
491
|
-
break;
|
|
492
|
-
default:
|
|
493
|
-
// ignore unknown codes
|
|
494
|
-
break;
|
|
495
|
-
}
|
|
496
|
-
};
|
|
497
|
-
// Split the incoming string and enable flags for each code
|
|
498
|
-
if (shakebug_type) {
|
|
499
|
-
const codes = String(shakebug_type).split(',').map(c => c.trim());
|
|
500
|
-
codes.forEach(enableFlag);
|
|
501
|
-
}
|
|
502
|
-
// Store raw type for reference
|
|
503
|
-
global.shakebug_type = shakebug_type;
|
|
504
|
-
// Update React state so UI re‑renders with new flags
|
|
505
|
-
setAllowBugReport(global.allowBugReport);
|
|
506
|
-
setAllowCrashFlag(global.allowCrashReport);
|
|
507
|
-
setAllowEventFlag(global.allowEvent);
|
|
508
|
-
setAllowReviewFlag(global.allowReview);
|
|
509
|
-
setAllowSessionFlag(global.allowSession); log.debug("------------------------------------------------------------------------------------------");
|
|
510
|
-
log.info('API response:', message);
|
|
511
|
-
log.debug("------------------------------------------------------------------------------------------");
|
|
512
|
-
if (global.allowSession) { StartSession(); }
|
|
513
|
-
} else {
|
|
514
|
-
if (Platform.OS == "android") {
|
|
515
|
-
global.isAndroidValid = false
|
|
516
|
-
}
|
|
517
|
-
else {
|
|
518
|
-
global.isIOSValid = false
|
|
519
|
-
}
|
|
520
|
-
log.debug("------------------------------------------------------------------------------------------")
|
|
521
|
-
log.warn(message);
|
|
522
|
-
log.debug("------------------------------------------------------------------------------------------")
|
|
523
|
-
global.application_id = ""
|
|
524
|
-
}
|
|
525
|
-
}
|
|
526
|
-
catch (err) {
|
|
527
|
-
log.error("Err", err)
|
|
528
|
-
if (err === "Network request failed" || err?.message === "Network request failed") {
|
|
529
|
-
log.warn("Please check your internet connection")
|
|
530
|
-
}
|
|
531
|
-
}
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
// For call Startsesstion and get session id
|
|
535
|
-
const StartSession = async () => {
|
|
536
|
-
if (global.session_id == "") {
|
|
537
|
-
try {
|
|
538
|
-
const { success, session_id: newSessionId, message } = await SessionStartApi(global.latitude, global.longitude, global.application_id);
|
|
539
|
-
if (success) {
|
|
540
|
-
global.session_id = newSessionId
|
|
541
|
-
log.debug("------------------------------------------------------------------------------------------")
|
|
542
|
-
log.info('API response:', message);
|
|
543
|
-
log.debug("------------------------------------------------------------------------------------------")
|
|
544
|
-
} else {
|
|
545
|
-
log.debug("------------------------------------------------------------------------------------------")
|
|
546
|
-
log.warn(message);
|
|
547
|
-
log.debug("------------------------------------------------------------------------------------------")
|
|
548
|
-
global.session_id = ""
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
catch (err) {
|
|
552
|
-
log.error("err", err)
|
|
553
|
-
}
|
|
554
|
-
}
|
|
555
|
-
|
|
556
|
-
DeviceInfo.isEmulator().then(res => {
|
|
557
|
-
if (res === true) {
|
|
558
|
-
log.info("Supports real device only");
|
|
559
|
-
}
|
|
560
|
-
})
|
|
561
|
-
}
|
|
562
|
-
|
|
563
696
|
// For handle error globally
|
|
564
697
|
setGlobalErrorHandler()
|
|
565
698
|
|
|
@@ -605,10 +738,15 @@ function Shakebug({ children, Android_appkey, iOS_appkey, showTutorialScreenFirs
|
|
|
605
738
|
OnPrees={() => {
|
|
606
739
|
setAlertText("")
|
|
607
740
|
setIsAlert(false)
|
|
741
|
+
connectionAlertShownRef.current = false;
|
|
608
742
|
}}
|
|
609
743
|
/>
|
|
610
744
|
|
|
611
|
-
<ReviewModal
|
|
745
|
+
<ReviewModal
|
|
746
|
+
color={ThemeColor}
|
|
747
|
+
visible={showModal && allowReviewFlag && global.allowReview && !!global.application_id}
|
|
748
|
+
onClose={() => { setShowModal(false) }}
|
|
749
|
+
/>
|
|
612
750
|
</View>
|
|
613
751
|
</ShakebugContext.Provider>
|
|
614
752
|
)
|