react-native-inapp-inspector 2.3.14 → 2.3.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.
- package/README.md +1 -0
- package/dist/commonjs/components/AnimatedEntrance.js +3 -3
- package/dist/commonjs/components/ConsoleLogCard.js +174 -100
- package/dist/commonjs/components/Inspector/AnalyticsTab.js +0 -22
- package/dist/commonjs/components/Inspector/ConsoleTab.js +25 -38
- package/dist/commonjs/components/Inspector/CrashTab.js +19 -28
- package/dist/commonjs/components/Inspector/DeviceInfoTab.js +198 -98
- package/dist/commonjs/components/Inspector/FeedbackModal.d.ts +7 -0
- package/dist/commonjs/components/Inspector/FeedbackModal.js +552 -0
- package/dist/commonjs/components/Inspector/InspectorHeader.js +58 -6
- package/dist/commonjs/components/Inspector/MainScreen.js +100 -58
- package/dist/commonjs/components/Inspector/NetworkTab.js +26 -371
- package/dist/commonjs/components/Inspector/NpmStarPrompt.d.ts +3 -0
- package/dist/commonjs/components/Inspector/NpmStarPrompt.js +494 -0
- package/dist/commonjs/components/Inspector/PerformanceTab.js +40 -7
- package/dist/commonjs/components/Inspector/ReduxTab.js +3 -23
- package/dist/commonjs/components/Inspector/SettingsPanel.js +1035 -173
- package/dist/commonjs/components/Inspector/StorageTab.js +23 -28
- package/dist/commonjs/components/Inspector/TabBar.js +50 -15
- package/dist/commonjs/components/JsonViewer.js +14 -2
- package/dist/commonjs/components/LogCard.js +428 -227
- package/dist/commonjs/components/NetworkIcons.d.ts +5 -0
- package/dist/commonjs/components/NetworkIcons.js +33 -2
- package/dist/commonjs/constants/version.d.ts +1 -1
- package/dist/commonjs/constants/version.js +1 -1
- package/dist/commonjs/customHooks/analyticsLogger.js +1 -1
- package/dist/commonjs/customHooks/consoleLogger.js +34 -2
- package/dist/commonjs/customHooks/crashHandler.js +1 -1
- package/dist/commonjs/customHooks/networkLogger.js +184 -26
- package/dist/commonjs/helpers/index.d.ts +1 -0
- package/dist/commonjs/helpers/index.js +1 -0
- package/dist/commonjs/helpers/remoteConfig.d.ts +4 -0
- package/dist/commonjs/helpers/remoteConfig.js +165 -0
- package/dist/commonjs/helpers/searchQueryParser.d.ts +1 -1
- package/dist/commonjs/helpers/searchQueryParser.js +39 -291
- package/dist/commonjs/helpers/telemetry.d.ts +5 -0
- package/dist/commonjs/helpers/telemetry.js +339 -8
- package/dist/commonjs/index.d.ts +1 -0
- package/dist/commonjs/index.js +173 -29
- package/dist/commonjs/styles/AppFonts.d.ts +2 -0
- package/dist/commonjs/styles/AppFonts.js +1 -0
- package/dist/commonjs/styles/index.d.ts +22 -0
- package/dist/commonjs/styles/index.js +19 -0
- package/dist/commonjs/types/enums.d.ts +1 -0
- package/dist/commonjs/types/enums.js +1 -0
- package/dist/commonjs/types/interfaces.d.ts +12 -0
- package/dist/esm/components/AnimatedEntrance.js +3 -3
- package/dist/esm/components/ConsoleLogCard.js +141 -100
- package/dist/esm/components/Inspector/AnalyticsTab.js +1 -23
- package/dist/esm/components/Inspector/ConsoleTab.js +26 -39
- package/dist/esm/components/Inspector/CrashTab.js +20 -29
- package/dist/esm/components/Inspector/DeviceInfoTab.js +198 -98
- package/dist/esm/components/Inspector/FeedbackModal.d.ts +7 -0
- package/dist/esm/components/Inspector/FeedbackModal.js +515 -0
- package/dist/esm/components/Inspector/InspectorHeader.js +60 -8
- package/dist/esm/components/Inspector/MainScreen.js +101 -59
- package/dist/esm/components/Inspector/NetworkTab.js +27 -372
- package/dist/esm/components/Inspector/NpmStarPrompt.d.ts +3 -0
- package/dist/esm/components/Inspector/NpmStarPrompt.js +454 -0
- package/dist/esm/components/Inspector/PerformanceTab.js +40 -7
- package/dist/esm/components/Inspector/ReduxTab.js +4 -24
- package/dist/esm/components/Inspector/SettingsPanel.js +1038 -176
- package/dist/esm/components/Inspector/StorageTab.js +23 -28
- package/dist/esm/components/Inspector/TabBar.js +50 -15
- package/dist/esm/components/JsonViewer.js +14 -2
- package/dist/esm/components/LogCard.js +422 -221
- package/dist/esm/components/NetworkIcons.d.ts +5 -0
- package/dist/esm/components/NetworkIcons.js +26 -0
- package/dist/esm/constants/version.d.ts +1 -1
- package/dist/esm/constants/version.js +1 -1
- package/dist/esm/customHooks/analyticsLogger.js +1 -1
- package/dist/esm/customHooks/consoleLogger.js +34 -2
- package/dist/esm/customHooks/crashHandler.js +1 -1
- package/dist/esm/customHooks/networkLogger.js +184 -26
- package/dist/esm/helpers/index.d.ts +1 -0
- package/dist/esm/helpers/index.js +1 -0
- package/dist/esm/helpers/remoteConfig.d.ts +4 -0
- package/dist/esm/helpers/remoteConfig.js +160 -0
- package/dist/esm/helpers/searchQueryParser.d.ts +1 -1
- package/dist/esm/helpers/searchQueryParser.js +39 -291
- package/dist/esm/helpers/telemetry.d.ts +5 -0
- package/dist/esm/helpers/telemetry.js +332 -9
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +171 -29
- package/dist/esm/styles/AppFonts.d.ts +2 -0
- package/dist/esm/styles/AppFonts.js +1 -0
- package/dist/esm/styles/index.d.ts +22 -0
- package/dist/esm/styles/index.js +19 -0
- package/dist/esm/types/enums.d.ts +1 -0
- package/dist/esm/types/enums.js +1 -0
- package/dist/esm/types/interfaces.d.ts +12 -0
- package/package.json +1 -1
- package/src/components/AnimatedEntrance.tsx +3 -3
- package/src/components/ConsoleLogCard.tsx +154 -103
- package/src/components/Inspector/AnalyticsTab.tsx +0 -23
- package/src/components/Inspector/ConsoleTab.tsx +27 -41
- package/src/components/Inspector/CrashTab.tsx +19 -28
- package/src/components/Inspector/DeviceInfoTab.tsx +224 -102
- package/src/components/Inspector/FeedbackModal.tsx +626 -0
- package/src/components/Inspector/InspectorHeader.tsx +83 -5
- package/src/components/Inspector/MainScreen.tsx +61 -6
- package/src/components/Inspector/NetworkTab.tsx +70 -480
- package/src/components/Inspector/NpmStarPrompt.tsx +532 -0
- package/src/components/Inspector/PerformanceTab.tsx +44 -8
- package/src/components/Inspector/ReduxTab.tsx +9 -24
- package/src/components/Inspector/SettingsPanel.tsx +1162 -197
- package/src/components/Inspector/StorageTab.tsx +27 -30
- package/src/components/Inspector/TabBar.tsx +57 -20
- package/src/components/JsonViewer.tsx +15 -2
- package/src/components/LogCard.tsx +528 -339
- package/src/components/NetworkIcons.tsx +92 -0
- package/src/constants/version.ts +1 -1
- package/src/customHooks/analyticsLogger.ts +1 -1
- package/src/customHooks/consoleLogger.ts +36 -3
- package/src/customHooks/crashHandler.ts +1 -1
- package/src/customHooks/networkLogger.ts +214 -26
- package/src/helpers/index.ts +1 -0
- package/src/helpers/remoteConfig.ts +212 -0
- package/src/helpers/searchQueryParser.ts +42 -284
- package/src/helpers/telemetry.ts +381 -10
- package/src/index.tsx +374 -211
- package/src/styles/AppFonts.ts +2 -0
- package/src/styles/index.ts +20 -1
- package/src/types/enums.ts +1 -0
- package/src/types/interfaces.ts +12 -0
|
@@ -0,0 +1,454 @@
|
|
|
1
|
+
import React, { useEffect, useRef, useState } from 'react';
|
|
2
|
+
import { Animated, Linking, Modal, Platform, StyleSheet, Text, TouchableOpacity, View, } from 'react-native';
|
|
3
|
+
import { AppColors } from '../../styles/AppColors';
|
|
4
|
+
import { AppFonts } from '../../styles/AppFonts';
|
|
5
|
+
import TouchableScale from '../TouchableScale';
|
|
6
|
+
import { loadSettings, saveSettings } from '../../helpers/settingsStore';
|
|
7
|
+
import { trackTelemetryEvent } from '../../helpers/telemetry';
|
|
8
|
+
import { StarIcon, CloseWhite, CheckIcon, GitHubIcon, NpmIcon, } from '../NetworkIcons';
|
|
9
|
+
const FIVE_DAYS_MS = 5 * 24 * 60 * 60 * 1000;
|
|
10
|
+
const GITHUB_REPO_URL = 'https://github.com/vengatmacuser/react-native-inapp-inspector';
|
|
11
|
+
const NPM_PACKAGE_URL = 'https://www.npmjs.com/package/react-native-inapp-inspector';
|
|
12
|
+
export const NpmStarPrompt = () => {
|
|
13
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
14
|
+
const slideAnim = useRef(new Animated.Value(200)).current;
|
|
15
|
+
const fadeAnim = useRef(new Animated.Value(0)).current;
|
|
16
|
+
const pulseAnim = useRef(new Animated.Value(1)).current;
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
let isMounted = true;
|
|
19
|
+
async function checkEligibility() {
|
|
20
|
+
try {
|
|
21
|
+
const settings = await loadSettings();
|
|
22
|
+
if (settings.starPromptActioned) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const now = Date.now();
|
|
26
|
+
const firstSeen = settings.starPromptFirstSeen || now;
|
|
27
|
+
if (!settings.starPromptFirstSeen) {
|
|
28
|
+
await saveSettings({
|
|
29
|
+
...settings,
|
|
30
|
+
starPromptFirstSeen: now,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
const lastShown = settings.starPromptLastShown || firstSeen;
|
|
34
|
+
const timeElapsed = now - lastShown;
|
|
35
|
+
if (timeElapsed >= FIVE_DAYS_MS) {
|
|
36
|
+
const shouldShow = Math.random() < 0.65;
|
|
37
|
+
if (shouldShow && isMounted) {
|
|
38
|
+
setTimeout(() => {
|
|
39
|
+
if (isMounted) {
|
|
40
|
+
openPrompt();
|
|
41
|
+
}
|
|
42
|
+
}, 1800);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
checkEligibility();
|
|
50
|
+
return () => {
|
|
51
|
+
isMounted = false;
|
|
52
|
+
};
|
|
53
|
+
}, []);
|
|
54
|
+
const openPrompt = async () => {
|
|
55
|
+
setIsOpen(true);
|
|
56
|
+
try {
|
|
57
|
+
const settings = await loadSettings();
|
|
58
|
+
await saveSettings({
|
|
59
|
+
...settings,
|
|
60
|
+
starPromptLastShown: Date.now(),
|
|
61
|
+
});
|
|
62
|
+
trackTelemetryEvent('npm_star_prompt_shown', {
|
|
63
|
+
trigger: '5_day_interval',
|
|
64
|
+
platform: Platform.OS,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
catch { }
|
|
68
|
+
Animated.parallel([
|
|
69
|
+
Animated.spring(slideAnim, {
|
|
70
|
+
toValue: 0,
|
|
71
|
+
friction: 8,
|
|
72
|
+
tension: 50,
|
|
73
|
+
useNativeDriver: true,
|
|
74
|
+
}),
|
|
75
|
+
Animated.timing(fadeAnim, {
|
|
76
|
+
toValue: 1,
|
|
77
|
+
duration: 250,
|
|
78
|
+
useNativeDriver: true,
|
|
79
|
+
}),
|
|
80
|
+
]).start();
|
|
81
|
+
Animated.loop(Animated.sequence([
|
|
82
|
+
Animated.timing(pulseAnim, {
|
|
83
|
+
toValue: 1.15,
|
|
84
|
+
duration: 900,
|
|
85
|
+
useNativeDriver: true,
|
|
86
|
+
}),
|
|
87
|
+
Animated.timing(pulseAnim, {
|
|
88
|
+
toValue: 1,
|
|
89
|
+
duration: 900,
|
|
90
|
+
useNativeDriver: true,
|
|
91
|
+
}),
|
|
92
|
+
])).start();
|
|
93
|
+
};
|
|
94
|
+
const closePrompt = (callback) => {
|
|
95
|
+
Animated.parallel([
|
|
96
|
+
Animated.timing(fadeAnim, {
|
|
97
|
+
toValue: 0,
|
|
98
|
+
duration: 180,
|
|
99
|
+
useNativeDriver: true,
|
|
100
|
+
}),
|
|
101
|
+
Animated.timing(slideAnim, {
|
|
102
|
+
toValue: 200,
|
|
103
|
+
duration: 180,
|
|
104
|
+
useNativeDriver: true,
|
|
105
|
+
}),
|
|
106
|
+
]).start(() => {
|
|
107
|
+
setIsOpen(false);
|
|
108
|
+
if (callback)
|
|
109
|
+
callback();
|
|
110
|
+
});
|
|
111
|
+
};
|
|
112
|
+
const handleStarNow = async () => {
|
|
113
|
+
try {
|
|
114
|
+
const settings = await loadSettings();
|
|
115
|
+
await saveSettings({
|
|
116
|
+
...settings,
|
|
117
|
+
starPromptActioned: true,
|
|
118
|
+
});
|
|
119
|
+
trackTelemetryEvent('npm_star_prompt_action', {
|
|
120
|
+
action: 'starred',
|
|
121
|
+
platform: Platform.OS,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
catch { }
|
|
125
|
+
closePrompt(() => {
|
|
126
|
+
Linking.openURL(GITHUB_REPO_URL).catch(() => {
|
|
127
|
+
Linking.openURL(NPM_PACKAGE_URL).catch(() => { });
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
};
|
|
131
|
+
const handleAlreadyStarred = async () => {
|
|
132
|
+
try {
|
|
133
|
+
const settings = await loadSettings();
|
|
134
|
+
await saveSettings({
|
|
135
|
+
...settings,
|
|
136
|
+
starPromptActioned: true,
|
|
137
|
+
});
|
|
138
|
+
trackTelemetryEvent('npm_star_prompt_action', {
|
|
139
|
+
action: 'already_starred',
|
|
140
|
+
platform: Platform.OS,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
catch { }
|
|
144
|
+
closePrompt();
|
|
145
|
+
};
|
|
146
|
+
const handleRemindLater = async () => {
|
|
147
|
+
try {
|
|
148
|
+
const settings = await loadSettings();
|
|
149
|
+
await saveSettings({
|
|
150
|
+
...settings,
|
|
151
|
+
starPromptLastShown: Date.now(),
|
|
152
|
+
});
|
|
153
|
+
trackTelemetryEvent('npm_star_prompt_action', {
|
|
154
|
+
action: 'remind_later',
|
|
155
|
+
platform: Platform.OS,
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
catch { }
|
|
159
|
+
closePrompt();
|
|
160
|
+
};
|
|
161
|
+
const handleDontAskAgain = async () => {
|
|
162
|
+
try {
|
|
163
|
+
const settings = await loadSettings();
|
|
164
|
+
await saveSettings({
|
|
165
|
+
...settings,
|
|
166
|
+
starPromptActioned: true,
|
|
167
|
+
});
|
|
168
|
+
trackTelemetryEvent('npm_star_prompt_action', {
|
|
169
|
+
action: 'dont_ask_again',
|
|
170
|
+
platform: Platform.OS,
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
catch { }
|
|
174
|
+
closePrompt();
|
|
175
|
+
};
|
|
176
|
+
if (!isOpen)
|
|
177
|
+
return null;
|
|
178
|
+
return (<Modal transparent visible={isOpen} animationType="none" onRequestClose={handleRemindLater}>
|
|
179
|
+
<Animated.View style={[
|
|
180
|
+
styles.backdrop,
|
|
181
|
+
{
|
|
182
|
+
opacity: fadeAnim,
|
|
183
|
+
},
|
|
184
|
+
]}>
|
|
185
|
+
<TouchableOpacity style={StyleSheet.absoluteFill} activeOpacity={1} onPress={handleRemindLater}/>
|
|
186
|
+
|
|
187
|
+
<Animated.View style={[
|
|
188
|
+
styles.cardContainer,
|
|
189
|
+
{
|
|
190
|
+
transform: [{ translateY: slideAnim }],
|
|
191
|
+
},
|
|
192
|
+
]}>
|
|
193
|
+
|
|
194
|
+
<View style={styles.headerIconWrapper}>
|
|
195
|
+
<Animated.View style={[
|
|
196
|
+
styles.iconGlow,
|
|
197
|
+
{
|
|
198
|
+
transform: [{ scale: pulseAnim }],
|
|
199
|
+
},
|
|
200
|
+
]}/>
|
|
201
|
+
<View style={styles.iconCircle}>
|
|
202
|
+
<StarIcon size={26} color="#F59E0B"/>
|
|
203
|
+
</View>
|
|
204
|
+
</View>
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
<TouchableOpacity onPress={handleRemindLater} hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }} style={styles.closeBtn}>
|
|
208
|
+
<CloseWhite size={12} color={AppColors.grayText}/>
|
|
209
|
+
</TouchableOpacity>
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
<View style={styles.pillBadge}>
|
|
213
|
+
<Text style={styles.pillBadgeText}>SUPPORT OPEN SOURCE</Text>
|
|
214
|
+
</View>
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
<Text style={styles.title}>Enjoying In-App Inspector?</Text>
|
|
218
|
+
<Text style={styles.description}>
|
|
219
|
+
If this debugging tool saves you time, please consider giving us a
|
|
220
|
+
star on GitHub & npm. Your support helps us build more features!
|
|
221
|
+
</Text>
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
<View style={styles.metricsBar}>
|
|
225
|
+
<View style={styles.metricItem}>
|
|
226
|
+
<GitHubIcon size={13} color={AppColors.grayText}/>
|
|
227
|
+
<Text style={styles.metricText}>GitHub Star</Text>
|
|
228
|
+
</View>
|
|
229
|
+
<View style={styles.metricDot}/>
|
|
230
|
+
<View style={styles.metricItem}>
|
|
231
|
+
<NpmIcon size={13} color="#CB3837"/>
|
|
232
|
+
<Text style={styles.metricText}>npm Package</Text>
|
|
233
|
+
</View>
|
|
234
|
+
<View style={styles.metricDot}/>
|
|
235
|
+
<View style={styles.metricItem}>
|
|
236
|
+
<Text style={styles.metricText}>100% Free</Text>
|
|
237
|
+
</View>
|
|
238
|
+
</View>
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
<TouchableScale accessible={true} accessibilityRole="button" accessibilityLabel="Star on GitHub" onPress={handleStarNow} style={styles.primaryButton}>
|
|
242
|
+
<View style={styles.primaryButtonContent}>
|
|
243
|
+
<StarIcon size={16} color={AppColors.white}/>
|
|
244
|
+
<Text style={styles.primaryButtonText}>⭐ Star on GitHub & npm</Text>
|
|
245
|
+
</View>
|
|
246
|
+
</TouchableScale>
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
<TouchableScale accessible={true} accessibilityRole="button" accessibilityLabel="I already starred" onPress={handleAlreadyStarred} style={styles.secondaryButton}>
|
|
250
|
+
<View style={styles.secondaryButtonContent}>
|
|
251
|
+
<CheckIcon size={13} color={AppColors.purple}/>
|
|
252
|
+
<Text style={styles.secondaryButtonText}>I Already Starred</Text>
|
|
253
|
+
</View>
|
|
254
|
+
</TouchableScale>
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
<View style={styles.footerRow}>
|
|
258
|
+
<TouchableOpacity onPress={handleRemindLater} hitSlop={{ top: 8, bottom: 8, left: 8, right: 8 }}>
|
|
259
|
+
<Text style={styles.footerLinkText}>Remind Me Later</Text>
|
|
260
|
+
</TouchableOpacity>
|
|
261
|
+
|
|
262
|
+
<View style={styles.footerSeparator}/>
|
|
263
|
+
|
|
264
|
+
<TouchableOpacity onPress={handleDontAskAgain} hitSlop={{ top: 8, bottom: 8, left: 8, right: 8 }}>
|
|
265
|
+
<Text style={styles.footerLinkTextMuted}>Don't Ask Again</Text>
|
|
266
|
+
</TouchableOpacity>
|
|
267
|
+
</View>
|
|
268
|
+
</Animated.View>
|
|
269
|
+
</Animated.View>
|
|
270
|
+
</Modal>);
|
|
271
|
+
};
|
|
272
|
+
const styles = StyleSheet.create({
|
|
273
|
+
backdrop: {
|
|
274
|
+
...StyleSheet.absoluteFillObject,
|
|
275
|
+
backgroundColor: 'rgba(15, 23, 42, 0.65)',
|
|
276
|
+
justifyContent: 'center',
|
|
277
|
+
alignItems: 'center',
|
|
278
|
+
paddingHorizontal: 20,
|
|
279
|
+
zIndex: 99999,
|
|
280
|
+
},
|
|
281
|
+
cardContainer: {
|
|
282
|
+
width: '100%',
|
|
283
|
+
maxWidth: 380,
|
|
284
|
+
backgroundColor: AppColors.white,
|
|
285
|
+
borderRadius: 22,
|
|
286
|
+
padding: 22,
|
|
287
|
+
alignItems: 'center',
|
|
288
|
+
shadowColor: AppColors.black,
|
|
289
|
+
shadowOffset: { width: 0, height: 8 },
|
|
290
|
+
shadowOpacity: 0.22,
|
|
291
|
+
shadowRadius: 20,
|
|
292
|
+
elevation: 12,
|
|
293
|
+
borderWidth: 1.5,
|
|
294
|
+
borderColor: `${AppColors.purple}25`,
|
|
295
|
+
},
|
|
296
|
+
headerIconWrapper: {
|
|
297
|
+
position: 'relative',
|
|
298
|
+
alignItems: 'center',
|
|
299
|
+
justifyContent: 'center',
|
|
300
|
+
marginBottom: 12,
|
|
301
|
+
},
|
|
302
|
+
iconGlow: {
|
|
303
|
+
position: 'absolute',
|
|
304
|
+
width: 68,
|
|
305
|
+
height: 68,
|
|
306
|
+
borderRadius: 34,
|
|
307
|
+
backgroundColor: '#F59E0B22',
|
|
308
|
+
},
|
|
309
|
+
iconCircle: {
|
|
310
|
+
width: 54,
|
|
311
|
+
height: 54,
|
|
312
|
+
borderRadius: 27,
|
|
313
|
+
backgroundColor: '#FEF3C7',
|
|
314
|
+
borderWidth: 2,
|
|
315
|
+
borderColor: '#FDE68A',
|
|
316
|
+
alignItems: 'center',
|
|
317
|
+
justifyContent: 'center',
|
|
318
|
+
},
|
|
319
|
+
closeBtn: {
|
|
320
|
+
position: 'absolute',
|
|
321
|
+
top: 14,
|
|
322
|
+
right: 14,
|
|
323
|
+
width: 28,
|
|
324
|
+
height: 28,
|
|
325
|
+
borderRadius: 14,
|
|
326
|
+
backgroundColor: AppColors.grayBackground,
|
|
327
|
+
alignItems: 'center',
|
|
328
|
+
justifyContent: 'center',
|
|
329
|
+
},
|
|
330
|
+
pillBadge: {
|
|
331
|
+
backgroundColor: `${AppColors.purple}14`,
|
|
332
|
+
paddingHorizontal: 9,
|
|
333
|
+
paddingVertical: 3,
|
|
334
|
+
borderRadius: 10,
|
|
335
|
+
marginBottom: 8,
|
|
336
|
+
},
|
|
337
|
+
pillBadgeText: {
|
|
338
|
+
fontFamily: AppFonts.interBold,
|
|
339
|
+
fontSize: 9.5,
|
|
340
|
+
color: AppColors.purple,
|
|
341
|
+
letterSpacing: 0.6,
|
|
342
|
+
},
|
|
343
|
+
title: {
|
|
344
|
+
fontFamily: AppFonts.interBold,
|
|
345
|
+
fontSize: 18,
|
|
346
|
+
lineHeight: 23,
|
|
347
|
+
color: AppColors.primaryBlack,
|
|
348
|
+
textAlign: 'center',
|
|
349
|
+
marginBottom: 6,
|
|
350
|
+
},
|
|
351
|
+
description: {
|
|
352
|
+
fontFamily: AppFonts.interRegular,
|
|
353
|
+
fontSize: 12.5,
|
|
354
|
+
lineHeight: 18,
|
|
355
|
+
color: AppColors.grayText,
|
|
356
|
+
textAlign: 'center',
|
|
357
|
+
marginBottom: 14,
|
|
358
|
+
paddingHorizontal: 8,
|
|
359
|
+
},
|
|
360
|
+
metricsBar: {
|
|
361
|
+
flexDirection: 'row',
|
|
362
|
+
alignItems: 'center',
|
|
363
|
+
justifyContent: 'center',
|
|
364
|
+
backgroundColor: AppColors.grayBackground,
|
|
365
|
+
paddingVertical: 7,
|
|
366
|
+
paddingHorizontal: 14,
|
|
367
|
+
borderRadius: 10,
|
|
368
|
+
marginBottom: 16,
|
|
369
|
+
gap: 8,
|
|
370
|
+
},
|
|
371
|
+
metricItem: {
|
|
372
|
+
flexDirection: 'row',
|
|
373
|
+
alignItems: 'center',
|
|
374
|
+
gap: 4,
|
|
375
|
+
},
|
|
376
|
+
metricText: {
|
|
377
|
+
fontFamily: AppFonts.interMedium,
|
|
378
|
+
fontSize: 11,
|
|
379
|
+
color: AppColors.primaryBlack,
|
|
380
|
+
},
|
|
381
|
+
metricDot: {
|
|
382
|
+
width: 3.5,
|
|
383
|
+
height: 3.5,
|
|
384
|
+
borderRadius: 2,
|
|
385
|
+
backgroundColor: AppColors.dividerColor,
|
|
386
|
+
},
|
|
387
|
+
primaryButton: {
|
|
388
|
+
width: '100%',
|
|
389
|
+
backgroundColor: AppColors.purple,
|
|
390
|
+
borderRadius: 12,
|
|
391
|
+
paddingVertical: 12,
|
|
392
|
+
alignItems: 'center',
|
|
393
|
+
justifyContent: 'center',
|
|
394
|
+
marginBottom: 8,
|
|
395
|
+
shadowColor: AppColors.purple,
|
|
396
|
+
shadowOffset: { width: 0, height: 4 },
|
|
397
|
+
shadowOpacity: 0.3,
|
|
398
|
+
shadowRadius: 8,
|
|
399
|
+
elevation: 4,
|
|
400
|
+
},
|
|
401
|
+
primaryButtonContent: {
|
|
402
|
+
flexDirection: 'row',
|
|
403
|
+
alignItems: 'center',
|
|
404
|
+
gap: 7,
|
|
405
|
+
},
|
|
406
|
+
primaryButtonText: {
|
|
407
|
+
fontFamily: AppFonts.interBold,
|
|
408
|
+
fontSize: 14,
|
|
409
|
+
color: AppColors.white,
|
|
410
|
+
},
|
|
411
|
+
secondaryButton: {
|
|
412
|
+
width: '100%',
|
|
413
|
+
backgroundColor: `${AppColors.purple}10`,
|
|
414
|
+
borderWidth: 1,
|
|
415
|
+
borderColor: `${AppColors.purple}30`,
|
|
416
|
+
borderRadius: 12,
|
|
417
|
+
paddingVertical: 10,
|
|
418
|
+
alignItems: 'center',
|
|
419
|
+
justifyContent: 'center',
|
|
420
|
+
marginBottom: 14,
|
|
421
|
+
},
|
|
422
|
+
secondaryButtonContent: {
|
|
423
|
+
flexDirection: 'row',
|
|
424
|
+
alignItems: 'center',
|
|
425
|
+
gap: 6,
|
|
426
|
+
},
|
|
427
|
+
secondaryButtonText: {
|
|
428
|
+
fontFamily: AppFonts.interBold,
|
|
429
|
+
fontSize: 13,
|
|
430
|
+
color: AppColors.purple,
|
|
431
|
+
},
|
|
432
|
+
footerRow: {
|
|
433
|
+
flexDirection: 'row',
|
|
434
|
+
alignItems: 'center',
|
|
435
|
+
justifyContent: 'center',
|
|
436
|
+
gap: 12,
|
|
437
|
+
},
|
|
438
|
+
footerLinkText: {
|
|
439
|
+
fontFamily: AppFonts.interMedium,
|
|
440
|
+
fontSize: 11.5,
|
|
441
|
+
color: AppColors.grayText,
|
|
442
|
+
},
|
|
443
|
+
footerSeparator: {
|
|
444
|
+
width: 1,
|
|
445
|
+
height: 12,
|
|
446
|
+
backgroundColor: AppColors.dividerColor,
|
|
447
|
+
},
|
|
448
|
+
footerLinkTextMuted: {
|
|
449
|
+
fontFamily: AppFonts.interRegular,
|
|
450
|
+
fontSize: 11.5,
|
|
451
|
+
color: AppColors.grayTextWeak,
|
|
452
|
+
},
|
|
453
|
+
});
|
|
454
|
+
export default NpmStarPrompt;
|
|
@@ -13,6 +13,7 @@ import { getRuntimeDiagnostics } from '../../helpers';
|
|
|
13
13
|
import { SearchIcon, CircleXIcon, CircleAlertIcon, PerformanceIcon, BoltIcon, LightbulbIcon, MapIcon, AtomIcon, BrainIcon, GlobeIcon, ChevronIcon, } from '../NetworkIcons';
|
|
14
14
|
import { getPerformanceEvents, subscribePerformanceEvents, logPerformanceEvent, clearPerformanceEvents, } from '../../customHooks/performanceTracker';
|
|
15
15
|
import { startNativeFpsMonitoring, stopNativeFpsMonitoring, getNativeFpsMetrics, getNativeSystemMetrics, isNativeModuleAvailable, } from '../../native/NativeInspector';
|
|
16
|
+
import { trackInspectorScreenRecord } from '../../helpers/telemetry';
|
|
16
17
|
const PerformanceTab = React.memo(() => {
|
|
17
18
|
const { t } = useTranslation();
|
|
18
19
|
const [isRecording, setIsRecording] = useState(true);
|
|
@@ -148,10 +149,19 @@ const PerformanceTab = React.memo(() => {
|
|
|
148
149
|
}, [isRecording]);
|
|
149
150
|
const filteredEvents = useMemo(() => {
|
|
150
151
|
return events.filter(e => {
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
152
|
+
let matchSearch = true;
|
|
153
|
+
if (search && search.trim().length > 0) {
|
|
154
|
+
const queryTokens = search.trim().toLowerCase().split(/\s+/).filter(Boolean);
|
|
155
|
+
const corpus = [
|
|
156
|
+
e.label || '',
|
|
157
|
+
e.detail || '',
|
|
158
|
+
e.source || '',
|
|
159
|
+
e.category || '',
|
|
160
|
+
e.severity || '',
|
|
161
|
+
e.bottleneckThread || '',
|
|
162
|
+
].join(' ').toLowerCase();
|
|
163
|
+
matchSearch = queryTokens.every(tok => corpus.includes(tok));
|
|
164
|
+
}
|
|
155
165
|
const matchFilter = filterCategory === 'ALL'
|
|
156
166
|
? true
|
|
157
167
|
: filterCategory === 'JANKY'
|
|
@@ -328,7 +338,13 @@ const PerformanceTab = React.memo(() => {
|
|
|
328
338
|
</View>
|
|
329
339
|
|
|
330
340
|
|
|
331
|
-
<TouchableScale onPress={() =>
|
|
341
|
+
<TouchableScale onPress={() => {
|
|
342
|
+
setIsRecording(prev => {
|
|
343
|
+
const next = !prev;
|
|
344
|
+
trackInspectorScreenRecord(next ? 'start' : 'stop', 'performance_fps');
|
|
345
|
+
return next;
|
|
346
|
+
});
|
|
347
|
+
}} style={[
|
|
332
348
|
perfStyles.recordToggleBtn,
|
|
333
349
|
isRecording
|
|
334
350
|
? perfStyles.recordToggleActive
|
|
@@ -776,10 +792,27 @@ const PerformanceTab = React.memo(() => {
|
|
|
776
792
|
|
|
777
793
|
{filteredEvents.length === 0 ? (<View style={perfStyles.emptyCard}>
|
|
778
794
|
<BoltIcon color={AppColors.amber500} size={30}/>
|
|
779
|
-
<Text style={perfStyles.emptyTitle}>
|
|
795
|
+
<Text style={perfStyles.emptyTitle}>
|
|
796
|
+
{search.trim().length > 0 ? 'No Matching Events' : t('performance.emptyTitle')}
|
|
797
|
+
</Text>
|
|
780
798
|
<Text style={perfStyles.emptySub}>
|
|
781
|
-
{
|
|
799
|
+
{search.trim().length > 0
|
|
800
|
+
? `No performance events match "${search}"`
|
|
801
|
+
: t('performance.emptySubtitle')}
|
|
782
802
|
</Text>
|
|
803
|
+
{search.trim().length > 0 && (<TouchableScale onPress={() => setSearch('')} style={{
|
|
804
|
+
marginTop: 10,
|
|
805
|
+
paddingHorizontal: 14,
|
|
806
|
+
paddingVertical: 6,
|
|
807
|
+
borderRadius: 8,
|
|
808
|
+
backgroundColor: AppColors.grayBackground,
|
|
809
|
+
borderWidth: 1,
|
|
810
|
+
borderColor: AppColors.grayBorderSecondary,
|
|
811
|
+
}}>
|
|
812
|
+
<Text style={{ color: AppColors.brandPurple, fontSize: 12, fontFamily: AppFonts.interBold }}>
|
|
813
|
+
Clear Search
|
|
814
|
+
</Text>
|
|
815
|
+
</TouchableScale>)}
|
|
783
816
|
</View>) : (filteredEvents.map(event => {
|
|
784
817
|
const isOptimal = event.severity === 'optimal';
|
|
785
818
|
const isWarning = event.severity === 'warning';
|
|
@@ -12,7 +12,7 @@ import styles from '../../styles';
|
|
|
12
12
|
import { AppColors } from '../../styles/AppColors';
|
|
13
13
|
import { AppFonts } from '../../styles/AppFonts';
|
|
14
14
|
import { getActionHistory, getReduxAutoRefresh, setReduxAutoRefresh, } from '../../customHooks/reduxLogger';
|
|
15
|
-
import { TerminalIcon, SearchIcon, ClearIcon, LayersIcon, ClockIcon, ForwardChevronIcon, SortArrowIcon, BoltIcon, AtomIcon, ScreenIcon, ListenerIcon, DocIcon, LoadingSpinnerIcon, CircleAlertIcon, TextAaIcon, HeaderPauseIcon,
|
|
15
|
+
import { TerminalIcon, SearchIcon, ClearIcon, LayersIcon, ClockIcon, ForwardChevronIcon, SortArrowIcon, BoltIcon, AtomIcon, ScreenIcon, ListenerIcon, DocIcon, LoadingSpinnerIcon, CircleAlertIcon, TextAaIcon, HeaderPauseIcon, } from '../NetworkIcons';
|
|
16
16
|
const getOriginBadge = (originType) => {
|
|
17
17
|
switch (originType) {
|
|
18
18
|
case 'saga':
|
|
@@ -454,32 +454,12 @@ const ReduxTab = React.memo(() => {
|
|
|
454
454
|
</View>
|
|
455
455
|
|
|
456
456
|
|
|
457
|
-
<FlatList ref={listRef} data={filteredSlices} keyExtractor={item => item.id} renderItem={renderSliceItem} initialNumToRender={12} maxToRenderPerBatch={8} windowSize={5} removeClippedSubviews={true} renderToHardwareTextureAndroid={true} ListEmptyComponent={<EmptyState isSearch={reduxSearch.length > 0}
|
|
457
|
+
<FlatList ref={listRef} data={filteredSlices} keyExtractor={item => item.id} renderItem={renderSliceItem} initialNumToRender={12} maxToRenderPerBatch={8} windowSize={5} removeClippedSubviews={true} renderToHardwareTextureAndroid={true} ListEmptyComponent={<EmptyState isSearch={reduxSearch.trim().length > 0} searchQuery={reduxSearch} onClearSearch={() => setReduxSearch('')} customTitle={reduxSearch.trim().length > 0 ? 'No Matching Slices' : 'No Redux State Detected'} customSub={reduxSearch.trim().length > 0
|
|
458
|
+
? `No Redux slices match "${reduxSearch}"`
|
|
459
|
+
: 'Attach the Redux store or dispatch actions to see state slices.'}/>} ListFooterComponent={filteredSlices.length > 0 ? (<EndOfListFooter count={filteredSlices.length} label="slices"/>) : null} contentContainerStyle={[
|
|
458
460
|
reduxTabStyles.listContent,
|
|
459
461
|
filteredSlices.length === 0 && { flexGrow: 1 },
|
|
460
462
|
]} keyboardShouldPersistTaps="handled"/>
|
|
461
|
-
|
|
462
|
-
<TouchableScale onPress={() => {
|
|
463
|
-
try {
|
|
464
|
-
listRef.current?.scrollToOffset({
|
|
465
|
-
offset: 0,
|
|
466
|
-
animated: true,
|
|
467
|
-
});
|
|
468
|
-
}
|
|
469
|
-
catch {
|
|
470
|
-
try {
|
|
471
|
-
listRef.current?.scrollToIndex({
|
|
472
|
-
index: 0,
|
|
473
|
-
animated: true,
|
|
474
|
-
});
|
|
475
|
-
}
|
|
476
|
-
catch { }
|
|
477
|
-
}
|
|
478
|
-
}} hitSlop={12} style={styles.scrollTopBtn}>
|
|
479
|
-
<View style={{ transform: [{ rotate: '180deg' }] }}>
|
|
480
|
-
<ChevronIcon color={AppColors.white} size={18}/>
|
|
481
|
-
</View>
|
|
482
|
-
</TouchableScale>
|
|
483
463
|
</View>);
|
|
484
464
|
});
|
|
485
465
|
const reduxTabStyles = StyleSheet.create({
|