Skip to content

Commit 9af3812

Browse files
feat(example): add set user identification and attribute (#1153)
* feat(example): add set user identification and attribute
1 parent 3e2790f commit 9af3812

File tree

3 files changed

+243
-79
lines changed

3 files changed

+243
-79
lines changed
Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,48 @@
11
import React, { forwardRef } from 'react';
22

3-
import { KeyboardTypeOptions, StyleSheet, TextInput } from 'react-native';
3+
import { KeyboardTypeOptions, StyleSheet, TextInput, View } from 'react-native';
4+
import { Text } from 'native-base';
45

56
interface InputFieldProps {
67
placeholder?: string;
78
value?: string;
89
onChangeText?: (text: string) => void;
910
keyboardType?: KeyboardTypeOptions;
11+
errorText?: string;
12+
maxLength?: number;
13+
accessibilityLabel?: string;
14+
flex?: number;
1015
}
1116

1217
export const InputField = forwardRef<TextInput, InputFieldProps>(
13-
({ placeholder, value, onChangeText, keyboardType, ...restProps }, ref) => {
18+
(
19+
{
20+
placeholder,
21+
value,
22+
onChangeText,
23+
accessibilityLabel,
24+
maxLength,
25+
keyboardType,
26+
errorText,
27+
...restProps
28+
},
29+
ref,
30+
) => {
1431
return (
15-
<TextInput
16-
ref={ref}
17-
placeholder={placeholder}
18-
style={styles.textInput}
19-
keyboardType={keyboardType}
20-
value={value}
21-
onChangeText={onChangeText}
22-
{...restProps}
23-
/>
32+
<View>
33+
<TextInput
34+
ref={ref}
35+
placeholder={placeholder}
36+
style={styles.textInput}
37+
maxLength={maxLength}
38+
accessibilityLabel={accessibilityLabel}
39+
keyboardType={keyboardType}
40+
value={value}
41+
onChangeText={onChangeText}
42+
{...restProps}
43+
/>
44+
{errorText ? <Text style={styles.errorText}>{errorText}</Text> : null}
45+
</View>
2446
);
2547
},
2648
);
@@ -35,4 +57,7 @@ const styles = StyleSheet.create({
3557
fontSize: 16,
3658
borderRadius: 5,
3759
},
60+
errorText: {
61+
color: '#ff0000',
62+
},
3863
});

examples/default/src/navigation/RootTab.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import Icon from 'react-native-vector-icons/Ionicons';
88

99
import { SettingsScreen } from '../screens/SettingsScreen';
1010
import { HomeStackNavigator } from './HomeStack';
11+
import { Platform } from 'react-native';
1112

1213
export type RootTabParamList = {
1314
HomeStack: undefined;
@@ -22,7 +23,7 @@ const createTabBarIcon = (name: string): BottomTabNavigationOptions['tabBarIcon'
2223

2324
export const RootTabNavigator: React.FC = () => {
2425
return (
25-
<RootTab.Navigator>
26+
<RootTab.Navigator screenOptions={{ tabBarHideOnKeyboard: Platform.OS !== 'ios' }}>
2627
<RootTab.Screen
2728
name="HomeStack"
2829
component={HomeStackNavigator}
Lines changed: 205 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,83 +1,221 @@
11
import React, { useState } from 'react';
22

33
import Instabug, { BugReporting, ColorTheme, InvocationEvent } from 'instabug-reactnative';
4-
import { Input, InputGroup, InputLeftAddon } from 'native-base';
4+
import { InputGroup, InputLeftAddon, useToast, VStack, Button } from 'native-base';
55

66
import { ListTile } from '../components/ListTile';
77
import { Screen } from '../components/Screen';
88
import { Select } from '../components/Select';
9+
import { StyleSheet, View, ScrollView } from 'react-native';
10+
import { VerticalListTile } from '../components/VerticalListTile';
11+
import { InputField } from '../components/InputField';
912

1013
export const SettingsScreen: React.FC = () => {
1114
const [color, setColor] = useState('1D82DC');
15+
const [userEmail, setUserEmail] = useState('');
16+
const [userName, setUserName] = useState('');
17+
const [userID, setUserID] = useState('');
18+
const [userAttributeKey, setUserAttributeKey] = useState('');
19+
const [userAttributeValue, setUserAttributeValue] = useState('');
20+
const toast = useToast();
21+
const [userAttributesFormError, setUserAttributesFormError] = useState<any>({});
22+
23+
const validateUserAttributeForm = () => {
24+
const errors: any = {};
25+
if (userAttributeValue.length === 0) {
26+
errors.userAttributeValue = 'Value is required';
27+
}
28+
if (userAttributeKey.length === 0) {
29+
errors.userAttributeKey = 'Key is required';
30+
}
31+
setUserAttributesFormError(errors);
32+
return Object.keys(errors).length === 0;
33+
};
34+
const styles = StyleSheet.create({
35+
inputWrapper: {
36+
padding: 4,
37+
flex: 1,
38+
},
39+
40+
formContainer: {
41+
flexDirection: 'row',
42+
alignItems: 'stretch',
43+
},
44+
});
45+
46+
const clearUserAttributes = () => {
47+
Instabug.clearAllUserAttributes();
48+
toast.show({
49+
description: 'User Attributes cleared successfully',
50+
});
51+
};
52+
53+
const saveUserAttributes = () => {
54+
if (validateUserAttributeForm()) {
55+
Instabug.setUserAttribute(userAttributeKey, userAttributeValue);
56+
toast.show({
57+
description: 'User Attributes added successfully',
58+
});
59+
setUserAttributeKey('');
60+
setUserAttributeValue('');
61+
}
62+
};
63+
64+
const logout = () => {
65+
Instabug.logOut();
66+
toast.show({
67+
description: 'User logout successfully',
68+
});
69+
setUserID('');
70+
setUserName('');
71+
setUserEmail('');
72+
};
73+
74+
const identifyUser = () => {
75+
Instabug.identifyUser(userEmail, userName, userID);
76+
setUserID('');
77+
setUserName('');
78+
setUserEmail('');
79+
toast.show({
80+
description: 'User identified successfully',
81+
});
82+
};
1283

1384
return (
14-
<Screen>
15-
<ListTile title="Invocation Event">
16-
<Select
17-
label="Select Invocation Event"
18-
items={[
19-
{
20-
label: 'None',
21-
value: InvocationEvent.none,
22-
},
23-
{
24-
label: 'Shake',
25-
value: InvocationEvent.shake,
26-
},
27-
{
28-
label: 'Screenshot',
29-
value: InvocationEvent.screenshot,
30-
},
31-
{
32-
label: 'Two fingers swipe left',
33-
value: InvocationEvent.twoFingersSwipe,
34-
},
35-
{
36-
label: 'Floating button',
37-
value: InvocationEvent.floatingButton,
38-
isInitial: true,
39-
},
40-
]}
41-
onValueChange={(value) => {
42-
BugReporting.setInvocationEvents([value]);
43-
}}
44-
/>
45-
</ListTile>
46-
47-
<ListTile title="Primary Color">
48-
<InputGroup>
49-
<InputLeftAddon>#</InputLeftAddon>
50-
<Input
51-
value={color}
52-
maxLength={6}
53-
flex={1}
54-
accessibilityLabel="Primary Color Value"
55-
onChangeText={(value) => {
56-
setColor(value);
57-
if (/^[0-9A-F]{6}$/i.test(value)) {
58-
Instabug.setPrimaryColor(`#${value}`);
59-
}
85+
<ScrollView>
86+
<Screen>
87+
<ListTile title="Invocation Event">
88+
<Select
89+
label="Select Invocation Event"
90+
items={[
91+
{
92+
label: 'None',
93+
value: InvocationEvent.none,
94+
},
95+
{
96+
label: 'Shake',
97+
value: InvocationEvent.shake,
98+
},
99+
{
100+
label: 'Screenshot',
101+
value: InvocationEvent.screenshot,
102+
},
103+
{
104+
label: 'Two fingers swipe left',
105+
value: InvocationEvent.twoFingersSwipe,
106+
},
107+
{
108+
label: 'Floating button',
109+
value: InvocationEvent.floatingButton,
110+
isInitial: true,
111+
},
112+
]}
113+
onValueChange={(value) => {
114+
BugReporting.setInvocationEvents([value]);
60115
}}
61116
/>
62-
</InputGroup>
63-
</ListTile>
64-
65-
<ListTile title="Theme">
66-
<Select
67-
label="Select Theme"
68-
items={[
69-
{
70-
label: 'Light',
71-
value: ColorTheme.light,
72-
},
73-
{
74-
label: 'Dark',
75-
value: ColorTheme.dark,
76-
},
77-
]}
78-
onValueChange={Instabug.setColorTheme}
79-
/>
80-
</ListTile>
81-
</Screen>
117+
</ListTile>
118+
119+
<ListTile title="Primary Color">
120+
<InputGroup>
121+
<InputLeftAddon>#</InputLeftAddon>
122+
<InputField
123+
value={color}
124+
maxLength={6}
125+
accessibilityLabel="Primary Color Value"
126+
onChangeText={(value) => {
127+
setColor(value);
128+
if (/^[0-9A-F]{6}$/i.test(value)) {
129+
Instabug.setPrimaryColor(`#${value}`);
130+
}
131+
}}
132+
/>
133+
</InputGroup>
134+
</ListTile>
135+
136+
<ListTile title="Theme">
137+
<Select
138+
label="Select Theme"
139+
items={[
140+
{
141+
label: 'Light',
142+
value: ColorTheme.light,
143+
},
144+
{
145+
label: 'Dark',
146+
value: ColorTheme.dark,
147+
},
148+
]}
149+
onValueChange={Instabug.setColorTheme}
150+
/>
151+
</ListTile>
152+
153+
<VerticalListTile title="User Identification">
154+
<VStack>
155+
<View style={styles.formContainer}>
156+
<View style={styles.inputWrapper}>
157+
<InputField
158+
placeholder="User Email"
159+
keyboardType="email-address"
160+
onChangeText={(name) => setUserEmail(name)}
161+
value={userEmail}
162+
/>
163+
</View>
164+
<View style={styles.inputWrapper}>
165+
<InputField
166+
placeholder=" user name"
167+
onChangeText={(name) => setUserName(name)}
168+
value={userName}
169+
/>
170+
</View>
171+
<View style={styles.inputWrapper}>
172+
<InputField
173+
placeholder=" user id"
174+
onChangeText={(name) => setUserID(name)}
175+
value={userID}
176+
/>
177+
</View>
178+
</View>
179+
<Button mt="4" onPress={identifyUser}>
180+
Identify user
181+
</Button>
182+
183+
<Button mt="4" colorScheme="red" onPress={logout}>
184+
Logout user
185+
</Button>
186+
</VStack>
187+
</VerticalListTile>
188+
<VerticalListTile title="User Attributes">
189+
<VStack>
190+
<View style={styles.formContainer}>
191+
<View style={styles.inputWrapper}>
192+
<InputField
193+
placeholder="User attribute key"
194+
onChangeText={(key) => setUserAttributeKey(key)}
195+
value={userAttributeKey}
196+
errorText={userAttributesFormError.userAttributeKey}
197+
/>
198+
</View>
199+
<View style={styles.inputWrapper}>
200+
<InputField
201+
placeholder="User attribute value"
202+
onChangeText={(value) => setUserAttributeValue(value)}
203+
value={userAttributeValue}
204+
errorText={userAttributesFormError.userAttributeValue}
205+
/>
206+
</View>
207+
</View>
208+
209+
<Button mt="4" onPress={saveUserAttributes}>
210+
Save user attributes
211+
</Button>
212+
213+
<Button mt="4" colorScheme="red" onPress={clearUserAttributes}>
214+
Clear user attributes
215+
</Button>
216+
</VStack>
217+
</VerticalListTile>
218+
</Screen>
219+
</ScrollView>
82220
);
83221
};

0 commit comments

Comments
 (0)