diff --git a/examples/default/android/app/src/main/java/com/instabug/react/example/RNInstabugExampleCrashReportingModule.java b/examples/default/android/app/src/main/java/com/instabug/react/example/RNInstabugExampleCrashReportingModule.java index 4ccb7ad3ce..d10291dd31 100644 --- a/examples/default/android/app/src/main/java/com/instabug/react/example/RNInstabugExampleCrashReportingModule.java +++ b/examples/default/android/app/src/main/java/com/instabug/react/example/RNInstabugExampleCrashReportingModule.java @@ -28,11 +28,10 @@ public String getName() { } @ReactMethod - public void sendNativeNonFatal(final String exceptionObject) { + public void sendNativeNonFatal() { final IBGNonFatalException exception = new IBGNonFatalException.Builder(new IllegalStateException("Test exception")) .build(); CrashReporting.report(exception); - } @ReactMethod diff --git a/examples/default/ios/Podfile.lock b/examples/default/ios/Podfile.lock index 9cde707ae3..8204614422 100644 --- a/examples/default/ios/Podfile.lock +++ b/examples/default/ios/Podfile.lock @@ -2027,21 +2027,21 @@ SPEC CHECKSUMS: Instabug: 9e81b71be68626dafc74759f3458f7c5894dd2e1 instabug-reactnative-ndk: d765ac289d56e8896398d02760d9abf2562fc641 OCMock: 589f2c84dacb1f5aaf6e4cec1f292551fe748e74 - RCT-Folly: 4464f4d875961fce86008d45f4ecf6cef6de0740 + RCT-Folly: 34124ae2e667a0e5f0ea378db071d27548124321 RCTDeprecation: 726d24248aeab6d7180dac71a936bbca6a994ed1 RCTRequired: a94e7febda6db0345d207e854323c37e3a31d93b RCTTypeSafety: 28e24a6e44f5cbf912c66dde6ab7e07d1059a205 React: c2830fa483b0334bda284e46a8579ebbe0c5447e React-callinvoker: 4aecde929540c26b841a4493f70ebf6016691eb8 - React-Core: 9c059899f00d46b5cec3ed79251f77d9c469553d - React-CoreModules: 9fac2d31803c0ed03e4ddaa17f1481714f8633a5 - React-cxxreact: a979810a3ca4045ceb09407a17563046a7f71494 + React-Core: 32a581847d74ce9b5f51d9d11a4e4d132ad61553 + React-CoreModules: f53e0674e1747fa41c83bc970e82add97b14ad87 + React-cxxreact: 86f3b1692081fd954a0cb27cc90d14674645b64b React-debug: 3d21f69d8def0656f8b8ec25c0f05954f4d862c5 - React-defaultsnativemodule: 2fa2bdb7bd03ff9764facc04aa8520ebf14febae - React-domnativemodule: 986e6fe7569e1383dce452a7b013b6c843a752df - React-Fabric: 3bc7be9e3a6b7581fc828dc2aa041e107fc8ffb8 - React-FabricComponents: 668e0cb02344c2942e4c8921a643648faa6dc364 - React-FabricImage: 3f44dd25a2b020ed5215d4438a1bb1f3461cd4f1 + React-defaultsnativemodule: 2ed121c5a1edeab09cff382b8d9b538260f07848 + React-domnativemodule: 4393dd5dd7e13dbe42e69ebc791064a616990f91 + React-Fabric: cbf38ceefb1ac6236897abdb538130228e126695 + React-FabricComponents: dd4b01c4a60920d8dc15f3b5594c6fe9e7648a38 + React-FabricImage: 8b13aedfbd20f349b9b3314baf993c71c02995d9 React-featureflags: ee1abd6f71555604a36cda6476e3c502ca9a48e5 React-featureflagsnativemodule: 7ccc0cd666c2a6257401dceb7920818ac2b42803 React-graphics: d7dd9c8d75cad5af19e19911fa370f78f2febd96 @@ -2065,25 +2065,25 @@ SPEC CHECKSUMS: react-native-slider: 4a0f3386a38fc3d2d955efc515aef7096f7d1ee4 react-native-webview: c0b91a4598bd54e9fbc70353aebf1e9bab2e5bb9 React-nativeconfig: 8c83d992b9cc7d75b5abe262069eaeea4349f794 - React-NativeModulesApple: 9f7920224a3b0c7d04d77990067ded14cee3c614 + React-NativeModulesApple: 97f606f09fd9840b3868333984d6a0e7bcc425b5 React-perflogger: 59e1a3182dca2cee7b9f1f7aab204018d46d1914 - React-performancetimeline: a9d05533ff834c6aa1f532e05e571f3fd2e3c1ed + React-performancetimeline: 3e3f5c5576fe1cc2dd5fcfb1ae2046d5dceda3d7 React-RCTActionSheet: d80e68d3baa163e4012a47c1f42ddd8bcd9672cc - React-RCTAnimation: bde981f6bd7f8493696564da9b3bd05721d3b3cc - React-RCTAppDelegate: 0176615c51476c88212bf3edbafb840d39ea7631 - React-RCTBlob: 520a0382bf8e89b9153d60e3c6293e51615834e9 - React-RCTFabric: c9da097b19b30017a99498b8c66a69c72f3ce689 - React-RCTImage: 90448d2882464af6015ed57c98f463f8748be465 - React-RCTLinking: 1bd95d0a704c271d21d758e0f0388cced768d77d - React-RCTNetwork: 218af6e63eb9b47935cc5a775b7a1396cf10ff91 - React-RCTSettings: e10b8e42b0fce8a70fbf169de32a2ae03243ef6b - React-RCTText: e7bf9f4997a1a0b45c052d4ad9a0fe653061cf29 - React-RCTVibration: 5b70b7f11e48d1c57e0d4832c2097478adbabe93 + React-RCTAnimation: 051f0781709c5ed80ba8aa2b421dfb1d72a03162 + React-RCTAppDelegate: 106d225d076988b06aa4834e68d1ab754f40cacf + React-RCTBlob: 895eaf8bca2e76ee1c95b479235c6ccebe586fc6 + React-RCTFabric: 8d01df202ee9e933f9b5dd44b72ec89a7ac6ee01 + React-RCTImage: b73149c0cd54b641dba2d6250aaf168fee784d9f + React-RCTLinking: 23e519712285427e50372fbc6e0265d422abf462 + React-RCTNetwork: a5d06d122588031989115f293654b13353753630 + React-RCTSettings: 87d03b5d94e6eadd1e8c1d16a62f790751aafb55 + React-RCTText: 75e9dd39684f4bcd1836134ac2348efaca7437b3 + React-RCTVibration: 033c161fe875e6fa096d0d9733c2e2501682e3d4 React-rendererconsistency: f620c6e003e3c4593e6349d8242b8aeb3d4633f0 - React-rendererdebug: e697680f4dd117becc5daf9ea9800067abcee91c + React-rendererdebug: 5be7b834677b2a7a263f4d2545f0d4966cafad82 React-rncore: c22bd84cc2f38947f0414fab6646db22ff4f80cd - React-RuntimeApple: de0976836b90b484305638616898cbc665c67c13 - React-RuntimeCore: 3c4a5aa63d9e7a3c17b7fb23f32a72a8bcfccf57 + React-RuntimeApple: 71160e6c02efa07d198b84ef5c3a52a7d9d0399d + React-RuntimeCore: f88f79ec995c12af56a265d7505c7630733d9d82 React-runtimeexecutor: ea90d8e3a9e0f4326939858dafc6ab17c031a5d3 React-RuntimeHermes: c6b0afdf1f493621214eeb6517fb859ce7b21b81 React-runtimescheduler: 84f0d876d254bce6917a277b3930eb9bc29df6c7 @@ -2102,4 +2102,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: a1b532d67a1a86843e1f086101751ad55afa52da -COCOAPODS: 1.14.0 +COCOAPODS: 1.16.2 diff --git a/examples/default/src/components/InputField.tsx b/examples/default/src/components/InputField.tsx index feef8fd7b5..f3db99ed38 100644 --- a/examples/default/src/components/InputField.tsx +++ b/examples/default/src/components/InputField.tsx @@ -21,6 +21,7 @@ interface InputFieldProps { maxLength?: number; accessibilityLabel?: string; flex?: number; + testID?: string; } export const InputField = forwardRef( @@ -34,6 +35,7 @@ export const InputField = forwardRef( maxLength, keyboardType, errorText, + testID, ...restProps }, ref, @@ -43,11 +45,14 @@ export const InputField = forwardRef( @@ -63,9 +68,10 @@ const styles = StyleSheet.create({ borderWidth: 1, borderColor: '#ccc', paddingVertical: 10, - paddingHorizontal: 24, - fontSize: 16, + paddingHorizontal: 16, + fontSize: 12, borderRadius: 5, + color: 'black', }, errorText: { color: '#ff0000', diff --git a/examples/default/src/components/ListTile.tsx b/examples/default/src/components/ListTile.tsx index 35540dc85a..1652598196 100644 --- a/examples/default/src/components/ListTile.tsx +++ b/examples/default/src/components/ListTile.tsx @@ -1,25 +1,48 @@ import React, { PropsWithChildren } from 'react'; -import { Box, HStack, Pressable, Text } from 'native-base'; +import { Box, HStack, Pressable, Text, VStack } from 'native-base'; interface ListTileProps extends PropsWithChildren { title: string; + subtitle?: string; onPress?: () => void; + testID?: string; + truncateSubtitle?: boolean; } -export const ListTile: React.FC = ({ title, onPress, children }) => { +export const ListTile: React.FC = ({ + title, + subtitle, + onPress, + children, + testID, + truncateSubtitle = false, +}) => { return ( - {title} + + {title} + {subtitle && ( + + {subtitle} + + )} + {children} diff --git a/examples/default/src/components/PlatformListTile.tsx b/examples/default/src/components/PlatformListTile.tsx index 1bf1fe6e7d..bbee40444c 100644 --- a/examples/default/src/components/PlatformListTile.tsx +++ b/examples/default/src/components/PlatformListTile.tsx @@ -7,6 +7,7 @@ interface PlatformListTileProps extends PropsWithChildren { title: string; onPress?: () => void; platform?: 'ios' | 'android'; + testID?: string; } export const PlatformListTile: React.FC = ({ @@ -14,6 +15,7 @@ export const PlatformListTile: React.FC = ({ onPress, platform, children, + testID, }) => { if (Platform.OS === platform || !platform) { return ( @@ -25,7 +27,8 @@ export const PlatformListTile: React.FC = ({ borderBottomWidth="1" borderColor="coolGray.300" bg="coolGray.100" - _pressed={{ bg: 'coolGray.200' }}> + _pressed={{ bg: 'coolGray.200' }} + testID={testID}> {title} {children} diff --git a/examples/default/src/components/Select.tsx b/examples/default/src/components/Select.tsx index 206aa74e0e..0d81e655e2 100644 --- a/examples/default/src/components/Select.tsx +++ b/examples/default/src/components/Select.tsx @@ -6,15 +6,17 @@ interface SelectItem { label: string; value: T; isInitial?: boolean; + testID?: string; } interface SelectProps { label: string; items: SelectItem[]; onValueChange: (value: T) => void; + testID?: string; } -export function Select({ label, items, onValueChange }: SelectProps) { +export function Select({ label, items, onValueChange, testID }: SelectProps) { const initialItem = items.find((i) => i.isInitial) ?? items[0]; const [selectedItem, setSelectedItem] = useState(initialItem); @@ -35,7 +37,7 @@ export function Select({ label, items, onValueChange }: SelectProps) { endIcon: , }}> {items.map((item) => ( - + ))} ); diff --git a/examples/default/src/navigation/HomeStack.tsx b/examples/default/src/navigation/HomeStack.tsx index 090aa65873..2fefa84394 100644 --- a/examples/default/src/navigation/HomeStack.tsx +++ b/examples/default/src/navigation/HomeStack.tsx @@ -2,8 +2,41 @@ import React from 'react'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; -import { BugReportingScreen } from '../screens/BugReportingScreen'; +import { BugReportingScreen } from '../screens/bug-reporting/BugReportingScreen'; +import { + BugReportingStateScreen, + type BugReportingStateScreenProp, +} from '../screens/bug-reporting/BugReportingStateScreen'; +import { + ExtendedBugReportStateScreen, + type ExtendedBugReportStateScreenProp, +} from '../screens/bug-reporting/ExtendedBugReportStateScreen'; +import { + BugReportingTypesScreen, + type BugReportingTypesScreenProp, +} from '../screens/bug-reporting/BugReportingTypesScreen'; +import { + DisclaimerTextScreen, + type DisclaimerTextScreenProp, +} from '../screens/bug-reporting/DisclaimerTextScreen'; +import { + InvocationOptionsScreen, + type InvocationOptionsScreenProp, +} from '../screens/bug-reporting/InvocationOptionsScreen'; +import { + ViewHierarchyScreen, + type ViewHierarchyScreenProp, +} from '../screens/bug-reporting/ViewHierarchyScreen'; +import { + RepliesStateScreen, + type RepliesStateScreenProp, +} from '../screens/bug-reporting/RepliesStateScreen'; +import { UserConsentScreen } from '../screens/bug-reporting/UserConsentScreen'; import { CrashReportingScreen } from '../screens/CrashReportingScreen'; +import { + CrashReportingStateScreen, + type CrashReportingStateScreenProp, +} from '../screens/crash-reporting/CrashReportingStateScreen'; import { FeatureRequestsScreen } from '../screens/FeatureRequestsScreen'; import { HomeScreen } from '../screens/HomeScreen'; import { RepliesScreen } from '../screens/RepliesScreen'; @@ -31,11 +64,44 @@ import { HttpScreen } from '../screens/apm/HttpScreen'; import { WebViewsScreen } from '../screens/apm/webViews/WebViewsScreen'; import { FullWebViewsScreen } from '../screens/apm/webViews/FullWebViewsScreen'; import { PartialWebViewsScreen } from '../screens/apm/webViews/PartialWebViewsScreen'; +import { + InvocationEventsScreen, + type InvocationEventsScreenProp, +} from '../screens/bug-reporting/InvocationEventsScreen'; +import { + SessionProfilerScreen, + type SessionProfilerScreenProp, +} from '../screens/bug-reporting/SessionProfilerScreen'; +import { + NDKCrashesStateScreen, + type NDKCrashesStateScreenProp, +} from '../screens/crash-reporting/NDKCrashesStateScreen'; +import { NonFatalCrashesScreen } from '../screens/crash-reporting/NonFatalCrashesScreen'; +import { FatalCrashesScreen } from '../screens/crash-reporting/FatalCrashesScreen'; export type HomeStackParamList = { Home: undefined; + + // Bug Reporting // BugReporting: undefined; + BugReportingState: BugReportingStateScreenProp; + ExtendedBugReportState: ExtendedBugReportStateScreenProp; + BugReportingTypes: BugReportingTypesScreenProp; + DisclaimerText: DisclaimerTextScreenProp; + InvocationEvents: InvocationEventsScreenProp; + SessionProfiler: SessionProfilerScreenProp; + InvocationOptions: InvocationOptionsScreenProp; + ViewHierarchy: ViewHierarchyScreenProp; + RepliesState: RepliesStateScreenProp; + UserConsent: undefined; + + // Crash Reporting // CrashReporting: undefined; + CrashReportingState: CrashReportingStateScreenProp; + NDKCrashesState: NDKCrashesStateScreenProp; + NonFatalCrashes: undefined; + FatalCrashes: undefined; + FeatureRequests: undefined; Replies: undefined; Surveys: undefined; @@ -69,16 +135,91 @@ export const HomeStackNavigator: React.FC = () => { return ( + + {/* Bug Reporting */} + + + + + + + + + + + + {/* Crash Reporting */} + + + + + { - const toast = useToast(); - return ( - - Instabug.show()} /> - BugReporting.show(ReportType.bug, [])} /> - BugReporting.show(ReportType.feedback, [InvocationOption.emailFieldHidden])} - /> - BugReporting.show(ReportType.question, [])} /> - - BugReporting.setExtendedBugReportMode(ExtendedBugReportMode.enabledWithRequiredFields) - } - /> - - BugReporting.setExtendedBugReportMode(ExtendedBugReportMode.enabledWithOptionalFields) - } - /> - Instabug.setSessionProfilerEnabled(true)} - /> - Instabug.showWelcomeMessage(WelcomeMessageMode.beta)} - /> - Instabug.showWelcomeMessage(WelcomeMessageMode.live)} - /> - -
- - BugReporting.onInvokeHandler(function () { - Instabug.appendTags(['Invocation Handler tag1']); - }) - } - /> - - Instabug.onReportSubmitHandler(() => { - toast.show({ - description: 'Submission succeeded', - }); - }) - } - /> - - BugReporting.onSDKDismissedHandler(function () { - Instabug.setPrimaryColor('#FF0000'); - }) - } - /> -
-
- ); -}; diff --git a/examples/default/src/screens/CrashReportingScreen.tsx b/examples/default/src/screens/CrashReportingScreen.tsx index 397565ecd3..b30f2cb5bd 100644 --- a/examples/default/src/screens/CrashReportingScreen.tsx +++ b/examples/default/src/screens/CrashReportingScreen.tsx @@ -1,296 +1,72 @@ import React, { useState } from 'react'; -import { Alert, Platform, ScrollView, StyleSheet, Text, View, Switch } from 'react-native'; +import { Platform, ScrollView } from 'react-native'; -import { CrashReporting, NonFatalErrorLevel } from 'instabug-reactnative'; +import { CrashReporting } from 'instabug-reactnative'; import { ListTile } from '../components/ListTile'; import { Screen } from '../components/Screen'; -import { Section } from '../components/Section'; -import { PlatformListTile } from '../components/PlatformListTile'; -import { NativeExampleCrashReporting } from '../native/NativeCrashReporting'; -import { VerticalListTile } from '../components/VerticalListTile'; -import { Button, VStack } from 'native-base'; -import { InputField } from '../components/InputField'; -import { Select } from '../components/Select'; -import { showNotification } from '../utils/showNotification'; +import { Divider } from 'native-base'; -const styles = StyleSheet.create({ - inputWrapper: { - padding: 4, - flex: 1, - }, +import type { NativeStackScreenProps } from '@react-navigation/native-stack'; +import type { HomeStackParamList } from '../navigation/HomeStack'; - formContainer: { - flexDirection: 'row', - alignItems: 'stretch', - }, -}); - -export const CrashReportingScreen: React.FC = () => { - function throwHandledException(error: Error) { - try { - if (!error.message) { - const appName = 'Instabug Test App'; - error.message = `Handled ${error.name} From ${appName}`; - } - throw error; - } catch (err) { - if (err instanceof Error) { - CrashReporting.reportError(err, { level: NonFatalErrorLevel.critical }).then(() => - Alert.alert(`Crash report for ${error.name} is Sent!`), - ); - } - } - } - - function throwUnhandledException(error: Error, isPromise: boolean = false) { - const appName = 'Instabug Test App'; - const rejectionType = isPromise ? 'Promise Rejection ' : ''; - const errorMessage = `Unhandled ${rejectionType}${error.name} from ${appName}`; - - if (!error.message) { - console.log(`IBG-CRSH | Error message: ${error.message}`); - error.message = errorMessage; - } - - if (isPromise) { - console.log('IBG-CRSH | Promise'); - Promise.reject(error).then(() => - Alert.alert(`Promise Rejection Crash report for ${error.name} is Sent!`), - ); - } else { - throw error; - } - } - const [isEnabled, setIsEnabled] = useState(false); - - const [userAttributeKey, setUserAttributeKey] = useState(''); - const [userAttributeValue, setUserAttributeValue] = useState(''); - const [crashNameValue, setCrashNameValue] = useState(''); - const [crashFingerprint, setCrashFingerprint] = useState(''); - const [crashLevelValue, setCrashLevelValue] = useState( - NonFatalErrorLevel.error, - ); - - const toggleSwitch = (value: boolean) => { - setIsEnabled(value); - CrashReporting.setEnabled(value); - showNotification('Crash Reporting status', 'Crash Reporting enabled set to ' + value); - }; - - function sendCrash() { - try { - const error = new Error(crashNameValue); - - throw error; - } catch (err) { - if (err instanceof Error) { - const attrMap: { [k: string]: string } = {}; - attrMap[userAttributeKey] = userAttributeValue; - - const userAttributes: Record = {}; - if (userAttributeKey && userAttributeValue) { - userAttributes[userAttributeKey] = userAttributeValue; - } - const fingerprint = crashFingerprint.length === 0 ? undefined : crashFingerprint; - - CrashReporting.reportError(err, { - userAttributes: userAttributes, - fingerprint: fingerprint, - level: crashLevelValue, - }).then(() => { - Alert.alert(`Crash report for ${crashNameValue} is Sent!`); - }); - } - } - } +export const CrashReportingScreen: React.FC< + NativeStackScreenProps +> = ({ navigation }) => { + const [isEnabled, setIsEnabled] = useState(true); + const [isNDKEnabled, setIsNDKEnabled] = useState(true); return ( - - Crash Reporting Enabled: - - -
+ + + { + navigation.navigate('CrashReportingState', { + isEnabled, + setIsEnabled: (enabled: boolean) => { + setIsEnabled(enabled); + CrashReporting.setEnabled(enabled); + navigation.goBack(); + }, + }); + }} + testID="id_cr_state" + /> + + {Platform.OS === 'android' && ( throwHandledException(new Error())} + title="NDK Crashes State" + subtitle={isNDKEnabled ? 'Enabled' : 'Disabled'} + onPress={() => { + navigation.navigate('NDKCrashesState', { + isEnabled: isNDKEnabled, + setIsEnabled: (enabled: boolean) => { + setIsNDKEnabled(enabled); + CrashReporting.setNDKCrashesEnabled(enabled); + navigation.goBack(); + }, + }); + }} + testID="id_ndk_cr_state" /> - throwHandledException(new SyntaxError())} - /> - throwHandledException(new RangeError())} - /> - throwHandledException(new ReferenceError())} - /> - throwHandledException(new URIError())} - /> - NativeExampleCrashReporting.sendNativeNonFatal()} - /> - - - - setCrashNameValue(key)} - value={crashNameValue} - /> - - - - setUserAttributeKey(key)} - value={userAttributeKey} - /> - - - setUserAttributeValue(value)} - value={userAttributeValue} - /> - - - - + + + + + ); +}; diff --git a/examples/default/src/screens/bug-reporting/ExtendedBugReportStateScreen.tsx b/examples/default/src/screens/bug-reporting/ExtendedBugReportStateScreen.tsx new file mode 100644 index 0000000000..0591877064 --- /dev/null +++ b/examples/default/src/screens/bug-reporting/ExtendedBugReportStateScreen.tsx @@ -0,0 +1,46 @@ +import React from 'react'; + +import { ListTile } from '../../components/ListTile'; +import { Screen } from '../../components/Screen'; +import type { NativeStackScreenProps } from '@react-navigation/native-stack'; +import type { HomeStackParamList } from '../../navigation/HomeStack'; +import { ExtendedBugReportMode } from 'instabug-reactnative'; + +export enum ExtendedBugReportState { + Disabled = 'Disabled', + EnabledWithRequiredFields = 'EnabledWithRequiredFields', + EnabledWithOptionalFields = 'EnabledWithOptionalFields', +} + +export interface ExtendedBugReportStateScreenProp { + state: ExtendedBugReportState; + setState: (state: ExtendedBugReportState) => void; +} + +export const ExtendedBugReportStateScreen: React.FC< + NativeStackScreenProps +> = ({ navigation, route }) => { + const { state, setState } = route.params; + return ( + + setState(ExtendedBugReportState.Disabled)} + subtitle={state === ExtendedBugReportState.Disabled ? 'Selected' : undefined} + /> + setState(ExtendedBugReportState.EnabledWithRequiredFields)} + subtitle={state === ExtendedBugReportState.EnabledWithRequiredFields ? 'Selected' : undefined} + /> + setState(ExtendedBugReportState.EnabledWithOptionalFields)} + subtitle={state === ExtendedBugReportState.EnabledWithOptionalFields ? 'Selected' : undefined} + /> + + ); +}; diff --git a/examples/default/src/screens/bug-reporting/InvocationEventsScreen.tsx b/examples/default/src/screens/bug-reporting/InvocationEventsScreen.tsx new file mode 100644 index 0000000000..108237bc7c --- /dev/null +++ b/examples/default/src/screens/bug-reporting/InvocationEventsScreen.tsx @@ -0,0 +1,81 @@ +import React from 'react'; +import { Screen } from '../../components/Screen'; +import { ListTile } from '../../components/ListTile'; +import type { NativeStackScreenProps } from '@react-navigation/native-stack'; +import type { HomeStackParamList } from '../../navigation/HomeStack'; + +export interface InvocationEventsScreenProp { + selectedEvents: string[]; + setSelectedEvents: (events: string[]) => void; +} + +export const InvocationEventsScreen: React.FC< + NativeStackScreenProps +> = ({ navigation, route }) => { + const { selectedEvents, setSelectedEvents } = route.params; + + const isSelected = (events: string[]) => { + return ( + events.length === selectedEvents.length && + events.every((event) => selectedEvents.includes(event)) + ); + }; + + return ( + + setSelectedEvents(['floatingButton'])} + testID="id_floating_button" + subtitle={isSelected(['floatingButton']) ? 'Selected' : undefined} + /> + + setSelectedEvents(['twoFingersSwipe'])} + testID="id_two_fingers_swipe" + subtitle={isSelected(['twoFingersSwipe']) ? 'Selected' : undefined} + /> + + setSelectedEvents(['screenshot'])} + testID="id_screenshot" + subtitle={isSelected(['screenshot']) ? 'Selected' : undefined} + /> + + setSelectedEvents(['shake'])} + testID="id_shake" + subtitle={isSelected(['shake']) ? 'Selected' : undefined} + /> + + setSelectedEvents(['floatingButton', 'shake', 'screenshot'])} + testID="id_common" + subtitle={isSelected(['floatingButton', 'shake', 'screenshot']) ? 'Selected' : undefined} + /> + + + setSelectedEvents(['floatingButton', 'twoFingersSwipe', 'screenshot', 'shake']) + } + testID="id_all" + subtitle={ + isSelected(['floatingButton', 'twoFingersSwipe', 'screenshot', 'shake']) + ? 'Selected' + : undefined + } + /> + setSelectedEvents([])} + testID="id_none" + subtitle={isSelected([]) ? 'Selected' : undefined} + /> + + ); +}; diff --git a/examples/default/src/screens/bug-reporting/InvocationOptionsScreen.tsx b/examples/default/src/screens/bug-reporting/InvocationOptionsScreen.tsx new file mode 100644 index 0000000000..0f8dfc5ff3 --- /dev/null +++ b/examples/default/src/screens/bug-reporting/InvocationOptionsScreen.tsx @@ -0,0 +1,69 @@ +import React from 'react'; +import { Screen } from '../../components/Screen'; +import { ListTile } from '../../components/ListTile'; +import type { NativeStackScreenProps } from '@react-navigation/native-stack'; +import type { HomeStackParamList } from '../../navigation/HomeStack'; + +export interface InvocationOptionsScreenProp { + selectedOptions: string[]; + setSelectedOptions: (options: string[]) => void; +} + +export const InvocationOptionsScreen: React.FC< + NativeStackScreenProps +> = ({ navigation, route }) => { + const { selectedOptions, setSelectedOptions } = route.params; + + const isSelected = (options: string[]) => { + return ( + options.length === selectedOptions.length && + options.every((option) => selectedOptions.includes(option)) + ); + }; + + return ( + + setSelectedOptions(['commentFieldRequired'])} + testID="id_comment_field_required" + subtitle={isSelected(['commentFieldRequired']) ? 'Selected' : undefined} + /> + + setSelectedOptions(['emailFieldHidden'])} + testID="id_email_field_hidden" + subtitle={isSelected(['emailFieldHidden']) ? 'Selected' : undefined} + /> + + setSelectedOptions(['emailFieldOptional'])} + testID="id_email_field_optional" + subtitle={isSelected(['emailFieldOptional']) ? 'Selected' : undefined} + /> + + setSelectedOptions(['disablePostSendingDialog'])} + testID="id_disable_post_sending_dialog" + subtitle={isSelected(['disablePostSendingDialog']) ? 'Selected' : undefined} + /> + + setSelectedOptions(['commentFieldRequired', 'emailFieldHidden'])} + testID="id_comment_field_required_email_field_hidden" + subtitle={isSelected(['commentFieldRequired', 'emailFieldHidden']) ? 'Selected' : undefined} + /> + + setSelectedOptions([])} + testID="id_none" + subtitle={isSelected([]) ? 'Selected' : undefined} + /> + + ); +}; diff --git a/examples/default/src/screens/bug-reporting/RepliesStateScreen.tsx b/examples/default/src/screens/bug-reporting/RepliesStateScreen.tsx new file mode 100644 index 0000000000..a42dbeefac --- /dev/null +++ b/examples/default/src/screens/bug-reporting/RepliesStateScreen.tsx @@ -0,0 +1,33 @@ +import React from 'react'; +import { Screen } from '../../components/Screen'; +import { ListTile } from '../../components/ListTile'; +import type { NativeStackScreenProps } from '@react-navigation/native-stack'; +import type { HomeStackParamList } from '../../navigation/HomeStack'; + +export interface RepliesStateScreenProp { + isEnabled: boolean; + setIsEnabled: (enabled: boolean) => void; +} + +export const RepliesStateScreen: React.FC< + NativeStackScreenProps +> = ({ navigation, route }) => { + const { isEnabled, setIsEnabled } = route.params; + + return ( + + setIsEnabled(true)} + testID="id_enabled" + subtitle={isEnabled ? 'Selected' : undefined} + /> + setIsEnabled(false)} + testID="id_disabled" + subtitle={!isEnabled ? 'Selected' : undefined} + /> + + ); +}; diff --git a/examples/default/src/screens/bug-reporting/SessionProfilerScreen.tsx b/examples/default/src/screens/bug-reporting/SessionProfilerScreen.tsx new file mode 100644 index 0000000000..14b275c0a5 --- /dev/null +++ b/examples/default/src/screens/bug-reporting/SessionProfilerScreen.tsx @@ -0,0 +1,34 @@ +import React from 'react'; +import { Screen } from '../../components/Screen'; +import { ListTile } from '../../components/ListTile'; +import type { NativeStackScreenProps } from '@react-navigation/native-stack'; +import type { HomeStackParamList } from '../../navigation/HomeStack'; +import Instabug from 'instabug-reactnative'; + +export interface SessionProfilerScreenProp { + isEnabled: boolean; + setIsEnabled: (enabled: boolean) => void; +} + +export const SessionProfilerScreen: React.FC< + NativeStackScreenProps +> = ({ navigation, route }) => { + const { isEnabled, setIsEnabled } = route.params; + + return ( + + setIsEnabled(true)} + testID="id_enabled" + subtitle={isEnabled ? 'Selected' : undefined} + /> + setIsEnabled(false)} + testID="id_disabled" + subtitle={!isEnabled ? 'Selected' : undefined} + /> + + ); +}; diff --git a/examples/default/src/screens/bug-reporting/UserConsentScreen.tsx b/examples/default/src/screens/bug-reporting/UserConsentScreen.tsx new file mode 100644 index 0000000000..8845cef94f --- /dev/null +++ b/examples/default/src/screens/bug-reporting/UserConsentScreen.tsx @@ -0,0 +1,145 @@ +import React, { useState } from 'react'; +import { ScrollView, StyleSheet, View, Text, Alert } from 'react-native'; +import { BugReporting, userConsentActionType } from 'instabug-reactnative'; +import { Screen } from '../../components/Screen'; +import { Section } from '../../components/Section'; +import { Button, VStack } from 'native-base'; +import { InputField } from '../../components/InputField'; +import { Select } from '../../components/Select'; +import type { NativeStackScreenProps } from '@react-navigation/native-stack'; +import type { HomeStackParamList } from '../../navigation/HomeStack'; + +const styles = StyleSheet.create({ + inputWrapper: { + padding: 4, + flex: 1, + }, + inputTitle: { + fontSize: 12, + fontWeight: 'bold', + color: 'black', + paddingLeft: 4, + paddingBottom: 4, + }, +}); + +export const UserConsentScreen: React.FC< + NativeStackScreenProps +> = ({ navigation }) => { + const [key, setKey] = useState(''); + const [description, setDescription] = useState(''); + const [mandatory, setMandatory] = useState(false); + const [checked, setChecked] = useState(false); + const [actionType, setActionType] = useState(undefined); + + const handleSubmit = () => { + BugReporting.addUserConsent(key, description, mandatory, checked, actionType); + Alert.alert('User Consent Added', 'User consent added successfully'); + navigation.goBack(); + }; + + return ( + + +
+ + + Key + + + + Description + + + + Mandatory + setChecked(value === 'true')} + /> + + + Action Type + { + setCrashLevelValue(value); + }} + /> + + + + setCrashFingerprint(text)} + value={crashFingerprint} + testID="id_crash_fingerprint" + /> + + + +
+
+
+ + ); +};