shakebug-react-native 2.4.14 → 2.4.16

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 (32) hide show
  1. package/README.md +6 -0
  2. package/android/src/main/java/com/shakebug/ConnectivityReceiver.java +12 -7
  3. package/android/src/main/java/com/shakebug/DrawingView.java +13 -3
  4. package/android/src/main/java/com/shakebug/RecordScreenModule.java +6 -3
  5. package/android/src/main/java/com/shakebug/ViewShot.java +1 -0
  6. package/ios/CustomScreenShot/ShakebugSDKCustomScreenCapture.m +6 -2
  7. package/ios/ScreenShot/ShakebugCapture.m +3 -1
  8. package/ios/SketchCanvas/DrawingView.m +14 -1
  9. package/package.json +1 -1
  10. package/shakebug-react-native-2.4.15.tgz +0 -0
  11. package/src/APIs/MatchKey.js +1 -1
  12. package/src/Assets/images/shake.png +0 -0
  13. package/src/Assets/images/undo.png +0 -0
  14. package/src/Assets/images/undo@2x.png +0 -0
  15. package/src/Assets/images/undo@3x.png +0 -0
  16. package/src/Componanats/CustomAlert.js +8 -4
  17. package/src/Componanats/Icons.js +278 -0
  18. package/src/Componanats/KeyboardAvoidingWrapper.js +31 -39
  19. package/src/Componanats/LoadingModal.js +7 -4
  20. package/src/Componanats/NavigationContext.js +8 -1
  21. package/src/Componanats/ReviewModal.js +18 -11
  22. package/src/Componanats/SafeAreaHelper.js +70 -0
  23. package/src/Componanats/ShakeFunction.js +655 -364
  24. package/src/Componanats/ShakebugBottomSheet.js +729 -0
  25. package/src/Componanats/Theme.js +96 -0
  26. package/src/Componanats/ZoomableImage.js +350 -0
  27. package/src/Componanats/localization.js +111 -82
  28. package/src/Screens/AddDetailsScreen.js +800 -439
  29. package/src/Screens/FirstScreen.js +950 -540
  30. package/src/Screens/Shakebug.js +78 -44
  31. package/src/Screens/TrimVideoScreen.js +40 -7
  32. package/src/index.tsx +16 -7
@@ -10,6 +10,7 @@ import {
10
10
  Animated,
11
11
  Dimensions,
12
12
  Modal,
13
+ useColorScheme,
13
14
  } from 'react-native';
14
15
  import ShakeFunction from '../Componanats/ShakeFunction';
15
16
  import FirstScreen from './FirstScreen';
@@ -31,7 +32,7 @@ import { Localization } from '../Componanats/localization';
31
32
  import { GlobalStateProvider, useGlobalState } from '../Componanats/GlobalStateContext';
32
33
  import CustomeAlert from '../Componanats/CustomAlert';
33
34
  import ReviewModal from '../Componanats/ReviewModal';
34
- import { SafeAreaView } from 'react-native-safe-area-context';
35
+ import { isShakebugDark } from '../Componanats/Theme';
35
36
 
36
37
  console.ignoredYellowBox = ["Warning: Each", "Warning: Failed"];
37
38
 
@@ -63,7 +64,7 @@ global.isScreeenShotTaken = false;
63
64
  global.restrictedViews = [];
64
65
  global.currentScreen = ""
65
66
  global.isShakebugSDKOpen = false;
66
- global.sdk_version = "2.4.14";
67
+ global.sdk_version = "2.4.16";
67
68
  global.app_lunch_count = 0;
68
69
  global.POPUP_LAUNCH_THRESHOLD = 3;
69
70
  global.POPUP_COOLDOWN_DAYS = 2;
@@ -87,7 +88,8 @@ const ShakebugContext = React.createContext();
87
88
  // For navigation in register screen
88
89
  const NavigationContainer = ({ screens, setFocusedScreen }) => {
89
90
  const { navigationState } = useNavigation();
90
-
91
+ const colorScheme = useColorScheme();
92
+ const isDark = isShakebugDark(colorScheme);
91
93
 
92
94
  if (!navigationState || navigationState.length === 0) {
93
95
  return (
@@ -107,7 +109,7 @@ const NavigationContainer = ({ screens, setFocusedScreen }) => {
107
109
  }
108
110
 
109
111
  return (
110
- <View style={{ flex: 1, backgroundColor: 'white' }}>
112
+ <View style={{ flex: 1, backgroundColor: isDark ? '#21252c' : '#ffffff' }}>
111
113
  {navigationState.map((screen, index) => {
112
114
  const ScreenComponent = screens[screen.name];
113
115
  if (!ScreenComponent) return null;
@@ -154,6 +156,7 @@ const ShakeScreen = () => {
154
156
  showTutorialScreenFirstTime,
155
157
  FirstScreenTitle,
156
158
  SecondScreenTitle,
159
+ allowToReportBugByShaking,
157
160
  allowToReportBugByShakingMobile,
158
161
  allowToReportBugByScreenCapture,
159
162
  allowCrashReport,
@@ -161,8 +164,12 @@ const ShakeScreen = () => {
161
164
  ShakebugLanguage
162
165
  } = React.useContext(ShakebugContext);
163
166
 
164
- const resolvedAllowToReportBugByShaking = allowToReportBugByShakingMobile && allowBugReport;
165
- const resolvedAllowToReportBugByScreenCapture = allowToReportBugByScreenCapture && allowBugReport;
167
+ const shakingEnabled = (allowToReportBugByShaking !== undefined)
168
+ ? allowToReportBugByShaking
169
+ : (allowToReportBugByShakingMobile !== undefined ? allowToReportBugByShakingMobile : true);
170
+
171
+ const resolvedAllowToReportBugByShaking = shakingEnabled && (allowBugReport !== false);
172
+ const resolvedAllowToReportBugByScreenCapture = Boolean(allowToReportBugByScreenCapture) && (allowBugReport !== false);
166
173
  const resolvedAllowCrashReport = allowCrashReport;
167
174
 
168
175
  useEffect(() => {
@@ -195,16 +202,24 @@ function Shakebug({
195
202
  Android_appkey,
196
203
  iOS_appkey,
197
204
  showTutorialScreenFirstTime = true,
198
- ShakebugThemeColor = "#1dd3e3",
199
- changeSDKScreenTitle = ['Annotate your bug', 'Add Details'],
200
- allowToReportBugByShakingMobile = true,
205
+ ShakebugThemeColor = "#313A46",
206
+ changeSDKScreenTitle = ['Annotate your Bug', 'Feedback'],
207
+ allowToReportBugByShakingMobile,
208
+ allowToReportBugByShaking,
201
209
  allowToReportBugByScreenCapture = false,
202
210
  allowCrashReport = true,
203
211
  ShakebugLanguage = "ENGLISH",
204
212
  makeLogEnabled = false,
205
- setShakebugSDKEndPointURL = ["https://www.shakebug.com/api/v1.6/webservice.php/", "MarchShake2022", ""]
213
+ setShakebugSDKEndPointURL = ["https://www.shakebug.com/api/v1.6/webservice.php/", "MarchShake2022", ""],
214
+ theme = "auto"
206
215
  }) {
207
216
 
217
+ global.ShakebugTheme = theme;
218
+
219
+ const resolvedShakingOption = (allowToReportBugByShaking !== undefined)
220
+ ? allowToReportBugByShaking
221
+ : (allowToReportBugByShakingMobile !== undefined ? allowToReportBugByShakingMobile : true);
222
+
208
223
  const [allowBugReport, setAllowBugReport] = useState(true);
209
224
  const [allowCrashFlag, setAllowCrashFlag] = useState(true);
210
225
  const [allowEventFlag, setAllowEventFlag] = useState(true);
@@ -220,13 +235,14 @@ function Shakebug({
220
235
  : "ENGLISH";
221
236
  global.ShakebugLanguage = validLanguage;
222
237
 
223
- const ThemeColor = ShakebugThemeColor ? ShakebugThemeColor : "#1dd3e3";
238
+ const ThemeColor = ShakebugThemeColor ? ShakebugThemeColor : "#313A46";
239
+ global.ShakebugThemeColor = ThemeColor;
224
240
  const FirstScreenTitle = (changeSDKScreenTitle && changeSDKScreenTitle[0] && changeSDKScreenTitle[0] !== "")
225
241
  ? changeSDKScreenTitle[0]
226
- : Localization[validLanguage]?.FirstScreenTitle || "Annotate your bug";
242
+ : Localization[validLanguage]?.FirstScreenTitle || "Annotate your Bug";
227
243
  const SecondScreenTitle = (changeSDKScreenTitle && changeSDKScreenTitle[1] && changeSDKScreenTitle[1] !== "")
228
244
  ? changeSDKScreenTitle[1]
229
- : Localization[validLanguage]?.SecondScreenTitle || "Add Details";
245
+ : Localization[validLanguage]?.SecondScreenTitle || "Feedback";
230
246
  const [isAlert, setIsAlert] = useState(false)
231
247
  const [isAlertText, setAlertText] = useState("")
232
248
  const [showModal, setShowModal] = useState(false);
@@ -241,6 +257,7 @@ function Shakebug({
241
257
 
242
258
  const connectionAlertShownRef = useRef(false);
243
259
  const isMatchingKeyRef = useRef(false);
260
+ const isMountedRef = useRef(true);
244
261
  const reviewTimeoutRef = useRef(null);
245
262
 
246
263
 
@@ -559,9 +576,48 @@ function Shakebug({
559
576
  }
560
577
  };
561
578
 
579
+ const executeMatchKeyWithRetry = async (retries = 2) => {
580
+ const success = await executeMatchKey();
581
+ if (!success && (!global.application_id || global.application_id === "") && retries > 0) {
582
+ setTimeout(() => {
583
+ if (isMountedRef.current && (!global.application_id || global.application_id === "")) {
584
+ executeMatchKeyWithRetry(retries - 1);
585
+ }
586
+ }, 2000);
587
+ }
588
+ };
589
+
590
+ const handleConnectivityChange = (state) => {
591
+ if (!isMountedRef.current || !state) return;
592
+
593
+ // Ignore unknown/null initial state until native connectivity is reported
594
+ if (state.isConnected === null && state.isInternetReachable === null) return;
595
+
596
+ const isConnected = state.isConnected === true || state.isInternetReachable === true;
597
+ const lang = (global.ShakebugLanguage && Localization[global.ShakebugLanguage])
598
+ ? global.ShakebugLanguage
599
+ : "ENGLISH";
600
+ const errorMsg = Localization[lang]?.InterNetConnetionError || "Please check your internet connection";
601
+
602
+ if (!isConnected) {
603
+ setAlertText(errorMsg);
604
+ setIsAlert(true);
605
+ connectionAlertShownRef.current = true;
606
+ } else {
607
+ // Unconditionally dismiss any connection error alert when connection is restored
608
+ setIsAlert(false);
609
+ setAlertText("");
610
+ connectionAlertShownRef.current = false;
611
+
612
+ if (!global.application_id || global.application_id === "") {
613
+ executeMatchKeyWithRetry();
614
+ }
615
+ }
616
+ };
617
+
562
618
  // For check mau limit, valid appkey, handle connectivity, and call MatchKeyFunc
563
619
  useEffect(() => {
564
- let isMounted = true;
620
+ isMountedRef.current = true;
565
621
 
566
622
  async function initLaunchData() {
567
623
  try {
@@ -602,34 +658,6 @@ function Shakebug({
602
658
 
603
659
  initLaunchData();
604
660
 
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;
626
- }
627
- if (!global.application_id || global.application_id === "") {
628
- executeMatchKey();
629
- }
630
- }
631
- };
632
-
633
661
  // Check immediate connectivity on mount
634
662
  NetInfo.fetch().then(handleConnectivityChange).catch(() => {});
635
663
 
@@ -637,7 +665,7 @@ function Shakebug({
637
665
  const unsubscribe = NetInfo.addEventListener(handleConnectivityChange);
638
666
 
639
667
  return () => {
640
- isMounted = false;
668
+ isMountedRef.current = false;
641
669
  if (unsubscribe) {
642
670
  unsubscribe();
643
671
  }
@@ -650,6 +678,11 @@ function Shakebug({
650
678
  // For close or start session according app state
651
679
  useEffect(() => {
652
680
  const handleAppStateChange = (nextAppState) => {
681
+ if (nextAppState === 'active') {
682
+ // Re-check connectivity whenever app becomes active to catch any connection changes
683
+ // made while the app was backgrounded or inactive (e.g. toggled in Settings or Control Center)
684
+ NetInfo.fetch().then(handleConnectivityChange).catch(() => {});
685
+ }
653
686
  if (global.IsBackground == 'true') {
654
687
  if (nextAppState == 'active' && global.IsBackground == 'true') {
655
688
  if (Platform.OS == 'android' && global.isAndroidValid) {
@@ -704,7 +737,8 @@ function Shakebug({
704
737
  showTutorialScreenFirstTime,
705
738
  FirstScreenTitle,
706
739
  SecondScreenTitle,
707
- allowToReportBugByShaking: allowToReportBugByShakingMobile && allowBugReport,
740
+ allowToReportBugByShaking: resolvedShakingOption && allowBugReport,
741
+ allowToReportBugByShakingMobile: resolvedShakingOption && allowBugReport,
708
742
  allowToReportBugByScreenCapture: allowToReportBugByScreenCapture && allowBugReport,
709
743
  allowCrashReport: allowCrashReport && allowCrashFlag,
710
744
  allowBugReport,
@@ -1,4 +1,4 @@
1
- import { DeviceEventEmitter, NativeEventEmitter, NativeModules, Platform, SafeAreaView, StatusBar, View } from 'react-native'
1
+ import { BackHandler, DeviceEventEmitter, NativeEventEmitter, NativeModules, Platform, SafeAreaView, StatusBar, View } from 'react-native'
2
2
  import React, { useEffect, useState } from 'react'
3
3
  import { showEditor } from '../../trimVideo/src/index';
4
4
  import { useNavigation } from '../Componanats/NavigationContext';
@@ -9,10 +9,10 @@ console.ignoredYellowBox = ["Warning: Each", "Warning: Failed"];
9
9
 
10
10
  const TrimVideoScreen = ({ video, themeColor, SDKScreenTitle, Type, UpdateStatusBar, updateParent }) => {
11
11
 
12
- const { goToScreenAtIndex, navigate, goBack } = useNavigation();
12
+ const { goToScreenAtIndex, navigate, replace, goBack } = useNavigation();
13
13
  const [loading, setLoading] = useState(true);
14
14
 
15
- const ThemeColor = themeColor ? themeColor : "#1dd3e3";
15
+ const ThemeColor = themeColor ? themeColor : "#313A46";
16
16
 
17
17
  // For display video trimmer
18
18
  useEffect(() => {
@@ -39,6 +39,16 @@ const TrimVideoScreen = ({ video, themeColor, SDKScreenTitle, Type, UpdateStatus
39
39
  saveDialogConfirmText: Localization[global.ShakebugLanguage].Yes
40
40
  });
41
41
 
42
+ const handleExitToApp = () => {
43
+ global.isTrigger = false;
44
+ global.isShakebugOpen = false;
45
+ global.isScreenShotDetected = false;
46
+ global.isScreeenShotTaken = false;
47
+ global.isShakebugSDKOpen = false;
48
+ global.IsBackground = 'true';
49
+ goToScreenAtIndex(0);
50
+ };
51
+
42
52
  const handleVideoTrimEvent = (event) => {
43
53
  switch (event.name) {
44
54
  case 'onShow': {
@@ -55,27 +65,49 @@ const TrimVideoScreen = ({ video, themeColor, SDKScreenTitle, Type, UpdateStatus
55
65
  case 'onFinishTrimming': {
56
66
  global.IsBackground = 'true';
57
67
  UpdateStatusBar();
58
- navigate("AddDetailsScreen", { media: `${event.outputPath}`, mediaType: 'video', themeColor: themeColor, SDKScreenTitle: SDKScreenTitle, updateParent: updateParent });
68
+ if (Type === 'video' && typeof replace === 'function') {
69
+ replace("AddDetailsScreen", { media: `${event.outputPath}`, mediaType: 'video', themeColor: themeColor, SDKScreenTitle: SDKScreenTitle, updateParent: updateParent });
70
+ } else {
71
+ navigate("AddDetailsScreen", { media: `${event.outputPath}`, mediaType: 'video', themeColor: themeColor, SDKScreenTitle: SDKScreenTitle, updateParent: updateParent });
72
+ }
59
73
  return;
60
74
  }
61
75
  case 'onCancel': {
62
76
  UpdateStatusBar();
63
77
  if (Type == "video") {
64
- goToScreenAtIndex(1);
78
+ handleExitToApp();
65
79
  } else if (Type == "imgReplacedWithVideo") {
66
80
  goBack();
67
81
  } else if (Type == "videoReplacedWithVideo") {
68
- goToScreenAtIndex(3);
82
+ goBack();
69
83
  }
70
84
  return;
71
85
  }
72
86
  case 'onError': {
73
87
  setLoading(false);
88
+ UpdateStatusBar();
89
+ if (Type == "video") {
90
+ handleExitToApp();
91
+ } else {
92
+ goBack();
93
+ }
74
94
  break;
75
95
  }
76
96
  }
77
97
  };
78
98
 
99
+ const backAction = () => {
100
+ UpdateStatusBar();
101
+ if (Type == "video") {
102
+ handleExitToApp();
103
+ } else {
104
+ goBack();
105
+ }
106
+ return true;
107
+ };
108
+
109
+ const backHandler = BackHandler.addEventListener('hardwareBackPress', backAction);
110
+
79
111
  let subscription;
80
112
  if (Platform.OS === 'android') {
81
113
  subscription = DeviceEventEmitter.addListener('VideoTrim', handleVideoTrimEvent);
@@ -86,6 +118,7 @@ const TrimVideoScreen = ({ video, themeColor, SDKScreenTitle, Type, UpdateStatus
86
118
  }
87
119
 
88
120
  return () => {
121
+ backHandler.remove();
89
122
  if (subscription && subscription.remove) {
90
123
  subscription.remove();
91
124
  }
@@ -93,7 +126,7 @@ const TrimVideoScreen = ({ video, themeColor, SDKScreenTitle, Type, UpdateStatus
93
126
  }, [])
94
127
 
95
128
  return (
96
- <View style={{ flex: 1, backgroundColor: '#000', justifyContent: 'center', alignItems: 'center' }}>
129
+ <View style={{ flex: 1, backgroundColor: 'transparent', justifyContent: 'center', alignItems: 'center' }}>
97
130
  <LoadingModal visible={loading} color={ThemeColor} />
98
131
  </View>
99
132
  );
package/src/index.tsx CHANGED
@@ -21,11 +21,13 @@ export interface ShakebugViewProps {
21
21
  ShakebugThemeColor?: string;
22
22
  changeSDKScreenTitle?: string[];
23
23
  allowToReportBugByShakingMobile?: boolean;
24
+ allowToReportBugByShaking?: boolean;
24
25
  allowToReportBugByScreenCapture?: boolean;
25
26
  allowCrashReport?: boolean;
26
27
  makeLogEnabled?: boolean;
27
28
  ShakebugLanguage?: 'ENGLISH' | 'HINDI' | 'GUJARATI' | 'ARABIC' | 'CHINESE' | 'DUTCH' | 'FRENCH' | 'GERMAN' | 'GREEK' | 'INDONESIAN' | 'ITALIAN' | 'JAPANESE' | 'KOREAN' | 'RUSSIAN' | 'SPANISH' | 'TURKISH' | 'UKRAINIAN' | 'MARATHI' | 'TAMIL' | 'TELUGU';
28
29
  setShakebugSDKEndPointURL?: string[];
30
+ theme?: 'auto' | 'light' | 'dark';
29
31
  }
30
32
 
31
33
 
@@ -35,16 +37,22 @@ const ShakebugView: React.FC<ShakebugViewProps> = ({
35
37
  Android_appkey,
36
38
  iOS_appkey,
37
39
  showTutorialScreenFirstTime = true,
38
- ShakebugThemeColor = '#1dd3e3',
39
- changeSDKScreenTitle = ['Annotate your Bug', 'Add Details'],
40
- allowToReportBugByShakingMobile = true,
40
+ ShakebugThemeColor = '#272B32',
41
+ changeSDKScreenTitle = ['Annotate your bug', 'Add details'],
42
+ allowToReportBugByShakingMobile,
43
+ allowToReportBugByShaking,
41
44
  allowToReportBugByScreenCapture = false,
42
45
  allowCrashReport = true,
43
46
  makeLogEnabled = false,
44
47
  ShakebugLanguage = LocalLanguage != -1 ? Languages[LocalLanguage] : "ENGLISH",
45
- setShakebugSDKEndPointURL = ["https://www.shakebug.com/api/v1.6/webservice.php/", "MarchShake2022", ""]
48
+ setShakebugSDKEndPointURL = ["https://www.shakebug.com/api/v1.6/webservice.php/", "MarchShake2022", ""],
49
+ theme = 'auto',
46
50
  }) => {
47
51
 
52
+ const resolvedShaking = (allowToReportBugByShaking !== undefined)
53
+ ? allowToReportBugByShaking
54
+ : (allowToReportBugByShakingMobile !== undefined ? allowToReportBugByShakingMobile : true);
55
+
48
56
  return (
49
57
  <Shakebug
50
58
  children={children}
@@ -54,11 +62,12 @@ const ShakebugView: React.FC<ShakebugViewProps> = ({
54
62
  ShakebugThemeColor={ShakebugThemeColor}
55
63
  changeSDKScreenTitle={changeSDKScreenTitle}
56
64
  allowToReportBugByScreenCapture={allowToReportBugByScreenCapture}
57
- allowToReportBugByShakingMobile={allowToReportBugByShakingMobile}
65
+ allowToReportBugByShakingMobile={resolvedShaking}
58
66
  allowCrashReport={__DEV__ ? false : allowCrashReport}
59
67
  makeLogEnabled={makeLogEnabled}
60
68
  ShakebugLanguage={Languages.includes(ShakebugLanguage) ? ShakebugLanguage : LocalLanguage != -1 ? Languages[LocalLanguage] : "ENGLISH"}
61
69
  setShakebugSDKEndPointURL={setShakebugSDKEndPointURL}
70
+ theme={theme}
62
71
  />
63
72
  );
64
73
  };
@@ -70,13 +79,13 @@ export const addEventKey = (name: string, value: any): void => {
70
79
  };
71
80
 
72
81
  export const triggerBugReporting = (): void => {
73
- if (!global.allowBugReport) {
82
+ if (global.allowBugReport === false) {
74
83
  return;
75
84
  }
76
85
  global.isShakebugOpen = false;
77
86
  global.isTrigger = true;
78
87
  DeviceEventEmitter.emit('TriggerBugReportingEvent');
79
- }
88
+ };
80
89
 
81
90
  export const ShakebugSdkProtectedView = ({ children }) => {
82
91