react-native-inapp-inspector 2.0.5 → 2.0.7

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 (85) hide show
  1. package/android/src/main/java/com/inappinspector/NetworkInspectorModule.kt +11 -0
  2. package/dist/commonjs/components/Inspector/AuditTab.d.ts +3 -0
  3. package/dist/commonjs/components/Inspector/AuditTab.js +741 -0
  4. package/dist/commonjs/components/Inspector/DeviceTab.d.ts +3 -0
  5. package/dist/commonjs/components/Inspector/DeviceTab.js +717 -0
  6. package/dist/commonjs/components/Inspector/FirstTimeWalkthroughModal.d.ts +7 -0
  7. package/dist/commonjs/components/Inspector/FirstTimeWalkthroughModal.js +600 -0
  8. package/dist/commonjs/components/Inspector/InspectorHeader.js +28 -25
  9. package/dist/commonjs/components/Inspector/MainScreen.js +19 -2
  10. package/dist/commonjs/components/Inspector/NetworkDetail.js +15 -0
  11. package/dist/commonjs/components/Inspector/PerformanceHud.d.ts +7 -0
  12. package/dist/commonjs/components/Inspector/PerformanceHud.js +210 -0
  13. package/dist/commonjs/components/Inspector/PerformanceTab.js +30 -18
  14. package/dist/commonjs/components/Inspector/RequestReplayModal.d.ts +9 -0
  15. package/dist/commonjs/components/Inspector/RequestReplayModal.js +792 -0
  16. package/dist/commonjs/components/Inspector/RequestReplayView.d.ts +8 -0
  17. package/dist/commonjs/components/Inspector/RequestReplayView.js +871 -0
  18. package/dist/commonjs/components/Inspector/SettingsPanel.js +448 -49
  19. package/dist/commonjs/components/Inspector/StorageTab.d.ts +3 -0
  20. package/dist/commonjs/components/Inspector/StorageTab.js +610 -0
  21. package/dist/commonjs/components/Inspector/TabBar.js +23 -2
  22. package/dist/commonjs/components/NetworkIcons.d.ts +12 -0
  23. package/dist/commonjs/components/NetworkIcons.js +72 -3
  24. package/dist/commonjs/constants/version.d.ts +1 -1
  25. package/dist/commonjs/constants/version.js +1 -1
  26. package/dist/commonjs/customHooks/storageInspector.d.ts +13 -0
  27. package/dist/commonjs/customHooks/storageInspector.js +179 -0
  28. package/dist/commonjs/helpers/deviceInfo.d.ts +4 -0
  29. package/dist/commonjs/helpers/deviceInfo.js +94 -0
  30. package/dist/commonjs/helpers/index.d.ts +2 -0
  31. package/dist/commonjs/helpers/index.js +12 -1
  32. package/dist/commonjs/helpers/packageAuditor.d.ts +5 -0
  33. package/dist/commonjs/helpers/packageAuditor.js +182 -0
  34. package/dist/commonjs/helpers/settingsStore.d.ts +1 -1
  35. package/dist/commonjs/helpers/settingsStore.js +4 -2
  36. package/dist/commonjs/i18n/locales/en.json +3 -2
  37. package/dist/commonjs/index.d.ts +1 -0
  38. package/dist/commonjs/index.js +127 -9
  39. package/dist/commonjs/native/NativeInspector.d.ts +1 -0
  40. package/dist/commonjs/types/enums.d.ts +7 -0
  41. package/dist/commonjs/types/enums.js +7 -0
  42. package/dist/commonjs/types/interfaces.d.ts +77 -0
  43. package/dist/esm/components/Inspector/AuditTab.d.ts +3 -0
  44. package/dist/esm/components/Inspector/AuditTab.js +702 -0
  45. package/dist/esm/components/Inspector/DeviceTab.d.ts +3 -0
  46. package/dist/esm/components/Inspector/DeviceTab.js +678 -0
  47. package/dist/esm/components/Inspector/FirstTimeWalkthroughModal.d.ts +7 -0
  48. package/dist/esm/components/Inspector/FirstTimeWalkthroughModal.js +560 -0
  49. package/dist/esm/components/Inspector/InspectorHeader.js +28 -25
  50. package/dist/esm/components/Inspector/MainScreen.js +19 -2
  51. package/dist/esm/components/Inspector/NetworkDetail.js +16 -1
  52. package/dist/esm/components/Inspector/PerformanceHud.d.ts +7 -0
  53. package/dist/esm/components/Inspector/PerformanceHud.js +170 -0
  54. package/dist/esm/components/Inspector/PerformanceTab.js +31 -19
  55. package/dist/esm/components/Inspector/RequestReplayModal.d.ts +9 -0
  56. package/dist/esm/components/Inspector/RequestReplayModal.js +752 -0
  57. package/dist/esm/components/Inspector/RequestReplayView.d.ts +8 -0
  58. package/dist/esm/components/Inspector/RequestReplayView.js +831 -0
  59. package/dist/esm/components/Inspector/SettingsPanel.js +449 -50
  60. package/dist/esm/components/Inspector/StorageTab.d.ts +3 -0
  61. package/dist/esm/components/Inspector/StorageTab.js +571 -0
  62. package/dist/esm/components/Inspector/TabBar.js +24 -3
  63. package/dist/esm/components/NetworkIcons.d.ts +12 -0
  64. package/dist/esm/components/NetworkIcons.js +57 -0
  65. package/dist/esm/constants/version.d.ts +1 -1
  66. package/dist/esm/constants/version.js +1 -1
  67. package/dist/esm/customHooks/storageInspector.d.ts +13 -0
  68. package/dist/esm/customHooks/storageInspector.js +170 -0
  69. package/dist/esm/helpers/deviceInfo.d.ts +4 -0
  70. package/dist/esm/helpers/deviceInfo.js +89 -0
  71. package/dist/esm/helpers/index.d.ts +2 -0
  72. package/dist/esm/helpers/index.js +10 -0
  73. package/dist/esm/helpers/packageAuditor.d.ts +5 -0
  74. package/dist/esm/helpers/packageAuditor.js +173 -0
  75. package/dist/esm/helpers/settingsStore.d.ts +1 -1
  76. package/dist/esm/helpers/settingsStore.js +4 -2
  77. package/dist/esm/i18n/locales/en.json +3 -2
  78. package/dist/esm/index.d.ts +1 -0
  79. package/dist/esm/index.js +123 -8
  80. package/dist/esm/native/NativeInspector.d.ts +1 -0
  81. package/dist/esm/types/enums.d.ts +7 -0
  82. package/dist/esm/types/enums.js +7 -0
  83. package/dist/esm/types/interfaces.d.ts +77 -0
  84. package/ios/NetworkInspectorModule.mm +12 -5
  85. package/package.json +4 -1
@@ -0,0 +1,560 @@
1
+ import React, { useState } from 'react';
2
+ import { Pressable, StyleSheet, Text, View, } from 'react-native';
3
+ import Svg, { Circle, Path, Rect } from 'react-native-svg';
4
+ import TouchableScale from '../TouchableScale';
5
+ import { AppFonts } from '../../styles/AppFonts';
6
+ import { saveSettings } from '../../helpers/settingsStore';
7
+ import { CheckIcon, CloseWhite } from '../NetworkIcons';
8
+ // ─── SVG Icons for Walkthrough Steps ──────────────────────────────────────────
9
+ const ModulesIconSvg = ({ size = 18, color = '#818CF8', }) => (<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
10
+ <Rect x="3" y="3" width="7.5" height="7.5" rx="2" fill="rgba(129, 140, 248, 0.2)" stroke={color} strokeWidth="2"/>
11
+ <Rect x="13.5" y="3" width="7.5" height="7.5" rx="2" fill="rgba(129, 140, 248, 0.2)" stroke={color} strokeWidth="2"/>
12
+ <Rect x="3" y="13.5" width="7.5" height="7.5" rx="2" fill="rgba(129, 140, 248, 0.2)" stroke={color} strokeWidth="2"/>
13
+ <Rect x="13.5" y="13.5" width="7.5" height="7.5" rx="2" fill="rgba(129, 140, 248, 0.2)" stroke={color} strokeWidth="2"/>
14
+ </Svg>);
15
+ const SettingsGearIconSvg = ({ size = 18, color = '#818CF8', }) => (<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
16
+ <Circle cx="12" cy="12" r="3" stroke={color} strokeWidth="2" fill="rgba(129, 140, 248, 0.2)"/>
17
+ <Path d="M19.4 15a1.65 1.65 0 00.33 1.82l.06.06a2 2 0 010 2.83 2 2 0 01-2.83 0l-.06-.06a1.65 1.65 0 00-1.82-.33 1.65 1.65 0 00-1 1.51V21a2 2 0 01-2 2 2 2 0 01-2-2v-.09A1.65 1.65 0 009 19.4a1.65 1.65 0 00-1.82.33l-.06.06a2 2 0 01-2.83 0 2 2 0 010-2.83l.06-.06a1.65 1.65 0 00.33-1.82 1.65 1.65 0 00-1.51-1H3a2 2 0 01-2-2 2 2 0 012-2h.09A1.65 1.65 0 004.6 9a1.65 1.65 0 00-.33-1.82l-.06-.06a2 2 0 010-2.83 2 2 0 012.83 0l.06.06a1.65 1.65 0 001.82.33H9a1.65 1.65 0 001-1.51V3a2 2 0 012-2 2 2 0 012 2v.09a1.65 1.65 0 001 1.51 1.65 1.65 0 001.82-.33l.06-.06a2 2 0 012.83 0 2 2 0 010 2.83l-.06.06a1.65 1.65 0 00-.33 1.82V9a1.65 1.65 0 001.51 1H21a2 2 0 012 2 2 2 0 01-2 2h-.09a1.65 1.65 0 00-1.51 1z" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
18
+ </Svg>);
19
+ const DetailWorkbenchIconSvg = ({ size = 18, color = '#818CF8', }) => (<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
20
+ <Path d="M16 18l6-6-6-6M8 6l-6 6 6 6" stroke={color} strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round"/>
21
+ </Svg>);
22
+ const NetworkGlobeIconSvg = ({ size = 18, color = '#818CF8', }) => (<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
23
+ <Circle cx="12" cy="12" r="9.5" stroke={color} strokeWidth="2" fill="rgba(129, 140, 248, 0.15)"/>
24
+ <Path d="M2.5 12h19M12 2.5a14.5 14.5 0 013.8 9.5 14.5 14.5 0 01-3.8 9.5 14.5 14.5 0 01-3.8-9.5 14.5 14.5 0 013.8-9.5z" stroke={color} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/>
25
+ </Svg>);
26
+ const SearchFiltersIconSvg = ({ size = 18, color = '#818CF8', }) => (<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
27
+ <Circle cx="11" cy="11" r="7.5" stroke={color} strokeWidth="2" fill="rgba(129, 140, 248, 0.15)"/>
28
+ <Path d="M20.5 20.5l-4.2-4.2" stroke={color} strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round"/>
29
+ </Svg>);
30
+ const SkipIconSvg = ({ size = 12, color = '#CBD5E1', }) => (<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
31
+ <Path d="M5 4l10 8-10 8V4zM19 5v14" stroke={color} strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"/>
32
+ </Svg>);
33
+ const NextArrowSvg = ({ size = 12, color = '#FFFFFF', }) => (<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
34
+ <Path d="M5 12h14M12 5l7 7-7 7" stroke={color} strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"/>
35
+ </Svg>);
36
+ const BackArrowSvg = ({ size = 12, color = '#E0E7FF', }) => (<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
37
+ <Path d="M19 12H5M12 19l-7-7 7-7" stroke={color} strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"/>
38
+ </Svg>);
39
+ const PointerTopSvg = ({ align, offset = 24 }) => {
40
+ const containerStyle = [
41
+ styles.pointerSvgTop,
42
+ align === 'left' && { left: offset },
43
+ align === 'center' && { alignSelf: 'center' },
44
+ align === 'right' && { right: offset },
45
+ ];
46
+ return (<View style={containerStyle} pointerEvents="none">
47
+ <Svg width={20} height={10} viewBox="0 0 20 10">
48
+ <Path d="M0 10 L10 1 L20 10" fill="#13182C" stroke="rgba(129, 140, 248, 0.5)" strokeWidth="1.2"/>
49
+ <Path d="M1 10 L19 10" stroke="#13182C" strokeWidth="2.5"/>
50
+ </Svg>
51
+ </View>);
52
+ };
53
+ const PointerBottomSvg = ({ align, offset = 24 }) => {
54
+ const containerStyle = [
55
+ styles.pointerSvgBottom,
56
+ align === 'left' && { left: offset },
57
+ align === 'center' && { alignSelf: 'center' },
58
+ align === 'right' && { right: offset },
59
+ ];
60
+ return (<View style={containerStyle} pointerEvents="none">
61
+ <Svg width={20} height={10} viewBox="0 0 20 10">
62
+ <Path d="M0 0 L10 9 L20 0" fill="#13182C" stroke="rgba(129, 140, 248, 0.5)" strokeWidth="1.2"/>
63
+ <Path d="M1 0 L19 0" stroke="#13182C" strokeWidth="2.5"/>
64
+ </Svg>
65
+ </View>);
66
+ };
67
+ const TOOLTIP_STEPS = [
68
+ {
69
+ id: 'developer-modules',
70
+ stepNumber: 1,
71
+ totalSteps: 5,
72
+ badge: '1/5 • DEVELOPER MODULES',
73
+ iconComponent: <ModulesIconSvg size={18} color="#A5B4FC"/>,
74
+ title: '10+ Developer Tool Modules',
75
+ description: 'Switch seamlessly across Network APIs, Console Logs, Analytics event streams, Redux state trees, AsyncStorage/MMKV viewer, Device hardware/OS specs, and Performance audits.',
76
+ pointerPosition: 'top',
77
+ pointerAlign: 'left',
78
+ pointerOffset: 36,
79
+ cardTop: 108,
80
+ highlightBox: {
81
+ top: 54,
82
+ left: 8,
83
+ right: 8,
84
+ height: 46,
85
+ borderRadius: 10,
86
+ },
87
+ },
88
+ {
89
+ id: 'settings-hud',
90
+ stepNumber: 2,
91
+ totalSteps: 5,
92
+ badge: '2/5 • SETTINGS & CONTROLS',
93
+ iconComponent: <SettingsGearIconSvg size={18} color="#A5B4FC"/>,
94
+ title: 'Settings, RAM Limits & Live HUD',
95
+ description: 'Configure RAM-based auto limits to prevent memory bloat, customize tab ordering, toggle Dark/Light theme, and enable the live 60 FPS floating HUD overlay for on-screen performance monitoring.',
96
+ pointerPosition: 'top',
97
+ pointerAlign: 'right',
98
+ pointerOffset: 58,
99
+ cardTop: 56,
100
+ highlightBox: {
101
+ top: 8,
102
+ right: 52,
103
+ width: 38,
104
+ height: 38,
105
+ borderRadius: 10,
106
+ },
107
+ },
108
+ {
109
+ id: 'request-replay',
110
+ stepNumber: 3,
111
+ totalSteps: 5,
112
+ badge: '3/5 • DETAIL INSPECTOR & WORKBENCH',
113
+ iconComponent: <DetailWorkbenchIconSvg size={18} color="#A5B4FC"/>,
114
+ title: 'Deep Detail Pages & Replay Sandbox',
115
+ description: 'Tap any item to inspect syntax-highlighted JSON trees, payload diffs, full headers, and stack traces. Tap the Replay icon to launch the isolated Edit & Resend workbench.',
116
+ pointerPosition: 'top',
117
+ pointerAlign: 'center',
118
+ cardTop: 272,
119
+ highlightBox: {
120
+ top: 176,
121
+ left: 10,
122
+ right: 10,
123
+ height: 88,
124
+ borderRadius: 12,
125
+ },
126
+ },
127
+ {
128
+ id: 'network-apis',
129
+ stepNumber: 4,
130
+ totalSteps: 5,
131
+ badge: '4/5 • NETWORK TELEMETRY',
132
+ iconComponent: <NetworkGlobeIconSvg size={18} color="#A5B4FC"/>,
133
+ title: 'Real-Time Network Telemetry',
134
+ description: 'Zero-config auto-interception for Fetch, Axios, and XHR. Inspect round-trip latency, status codes, query params, headers, and colorized JSON response trees with instant cURL export.',
135
+ pointerPosition: 'top',
136
+ pointerAlign: 'left',
137
+ pointerOffset: 46,
138
+ cardTop: 106,
139
+ highlightBox: {
140
+ top: 57,
141
+ left: 12,
142
+ width: 92,
143
+ height: 38,
144
+ borderRadius: 10,
145
+ },
146
+ },
147
+ {
148
+ id: 'search-filters',
149
+ stepNumber: 5,
150
+ totalSteps: 5,
151
+ badge: '5/5 • SEARCH & SMART FILTERS',
152
+ iconComponent: <SearchFiltersIconSvg size={18} color="#A5B4FC"/>,
153
+ title: 'Instant Search & Status Filters',
154
+ description: 'Filter network traffic and logs instantly by status (2xx OK, Errors, Slow >500ms), regex expressions, or deep content matching across URLs, headers, and JSON keys.',
155
+ pointerPosition: 'top',
156
+ pointerAlign: 'center',
157
+ cardTop: 182,
158
+ highlightBox: {
159
+ top: 102,
160
+ left: 10,
161
+ right: 10,
162
+ height: 72,
163
+ borderRadius: 12,
164
+ },
165
+ },
166
+ ];
167
+ export const FirstTimeWalkthroughModal = ({ visible, onClose }) => {
168
+ const [currentStepIndex, setCurrentStepIndex] = useState(0);
169
+ const [dontShowAgain, setDontShowAgain] = useState(true);
170
+ React.useEffect(() => {
171
+ if (visible) {
172
+ setCurrentStepIndex(0);
173
+ }
174
+ }, [visible]);
175
+ if (!visible)
176
+ return null;
177
+ const currentStep = TOOLTIP_STEPS[currentStepIndex];
178
+ const isLastStep = currentStepIndex === TOOLTIP_STEPS.length - 1;
179
+ const handleFinish = async () => {
180
+ if (dontShowAgain) {
181
+ try {
182
+ await saveSettings({ hasCompletedWalkthrough: true });
183
+ }
184
+ catch {
185
+ // Safe fallback
186
+ }
187
+ }
188
+ onClose();
189
+ };
190
+ const handleNext = () => {
191
+ if (isLastStep) {
192
+ handleFinish();
193
+ }
194
+ else {
195
+ setCurrentStepIndex(prev => prev + 1);
196
+ }
197
+ };
198
+ const handlePrevious = () => {
199
+ if (currentStepIndex > 0) {
200
+ setCurrentStepIndex(prev => prev - 1);
201
+ }
202
+ };
203
+ return (<View style={styles.backdrop} pointerEvents="box-none">
204
+ {/* Semi-transparent Dimming Layer */}
205
+ <Pressable style={styles.scrim} onPress={handleFinish}/>
206
+
207
+ {/* Spotlight Halo Box around targeted UI element */}
208
+ {currentStep.highlightBox && (<View style={[
209
+ styles.spotlightRing,
210
+ {
211
+ top: currentStep.highlightBox.top,
212
+ bottom: currentStep.highlightBox.bottom,
213
+ left: currentStep.highlightBox.left,
214
+ right: currentStep.highlightBox.right,
215
+ width: currentStep.highlightBox.width,
216
+ height: currentStep.highlightBox.height,
217
+ borderRadius: currentStep.highlightBox.borderRadius || 12,
218
+ },
219
+ ]} pointerEvents="none"/>)}
220
+
221
+ {/* Contextual Tooltip Balloon Card */}
222
+ <View style={[
223
+ styles.tooltipCard,
224
+ currentStep.cardTop != null && { top: currentStep.cardTop },
225
+ currentStep.cardBottom != null && { bottom: currentStep.cardBottom },
226
+ ]}>
227
+ {/* Seamless SVG Pointer Beak (Pointing Up towards target) */}
228
+ {currentStep.pointerPosition === 'top' && (<PointerTopSvg align={currentStep.pointerAlign} offset={currentStep.pointerOffset}/>)}
229
+
230
+ {/* ─── 1. TOP HEADER & CONTROLS ─── */}
231
+ <View style={styles.cardHeader}>
232
+ <View style={styles.badgePill}>
233
+ <View style={styles.badgeDot}/>
234
+ <Text style={styles.badgeText}>{currentStep.badge}</Text>
235
+ </View>
236
+
237
+ <View style={styles.topActions}>
238
+ <TouchableScale style={styles.skipHeaderBtn} onPress={handleFinish} hitSlop={8}>
239
+ <SkipIconSvg size={11} color="#CBD5E1"/>
240
+ <Text style={styles.skipHeaderText}>Skip Tour</Text>
241
+ </TouchableScale>
242
+
243
+ <TouchableScale style={styles.closeBtn} onPress={handleFinish} hitSlop={10}>
244
+ <CloseWhite size={11} color="#CBD5E1"/>
245
+ </TouchableScale>
246
+ </View>
247
+ </View>
248
+
249
+ {/* ─── 2. TITLE & DESCRIPTION ─── */}
250
+ <View style={styles.contentSection}>
251
+ <View style={styles.titleRow}>
252
+ <View style={styles.iconContainer}>
253
+ {currentStep.iconComponent}
254
+ </View>
255
+ <Text style={styles.titleText} numberOfLines={1}>
256
+ {currentStep.title}
257
+ </Text>
258
+ </View>
259
+ <Text style={styles.descriptionText}>{currentStep.description}</Text>
260
+ </View>
261
+
262
+ {/* ─── 3. FOOTER (DOTS & NAVIGATION ACTIONS) ─── */}
263
+ <View style={styles.footerRow}>
264
+ {/* Progress Dots Indicator */}
265
+ <View style={styles.dotsContainer}>
266
+ {TOOLTIP_STEPS.map((s, idx) => (<Pressable key={s.id} onPress={() => setCurrentStepIndex(idx)} hitSlop={6}>
267
+ <View style={[
268
+ styles.dot,
269
+ currentStepIndex === idx && styles.dotActive,
270
+ ]}/>
271
+ </Pressable>))}
272
+ </View>
273
+
274
+ {/* Action Buttons */}
275
+ <View style={styles.btnGroup}>
276
+ {currentStepIndex > 0 && (<TouchableScale style={styles.backBtn} onPress={handlePrevious} hitSlop={6}>
277
+ <BackArrowSvg size={11} color="#E0E7FF"/>
278
+ <Text style={styles.backBtnText}>Back</Text>
279
+ </TouchableScale>)}
280
+
281
+ <TouchableScale style={[
282
+ styles.nextBtn,
283
+ isLastStep && styles.nextBtnFinal,
284
+ ]} onPress={handleNext} hitSlop={6}>
285
+ <Text style={styles.nextBtnText}>
286
+ {isLastStep ? 'Got It 🚀' : 'Next'}
287
+ </Text>
288
+ {!isLastStep && <NextArrowSvg size={11} color="#FFFFFF"/>}
289
+ </TouchableScale>
290
+ </View>
291
+ </View>
292
+
293
+ {/* Don't show again toggle */}
294
+ <TouchableScale style={styles.dontShowRow} onPress={() => setDontShowAgain(prev => !prev)} hitSlop={6}>
295
+ <View style={[
296
+ styles.checkbox,
297
+ dontShowAgain && styles.checkboxActive,
298
+ ]}>
299
+ {dontShowAgain && <CheckIcon size={9} color="#FFFFFF"/>}
300
+ </View>
301
+ <Text style={styles.dontShowText}>
302
+ Don't show tour on startup
303
+ </Text>
304
+ </TouchableScale>
305
+
306
+ {/* Seamless SVG Pointer Beak (Pointing Down towards target) */}
307
+ {currentStep.pointerPosition === 'bottom' && (<PointerBottomSvg align={currentStep.pointerAlign} offset={currentStep.pointerOffset}/>)}
308
+ </View>
309
+ </View>);
310
+ };
311
+ const styles = StyleSheet.create({
312
+ backdrop: {
313
+ position: 'absolute',
314
+ top: 0,
315
+ bottom: 0,
316
+ left: 0,
317
+ right: 0,
318
+ width: '100%',
319
+ height: '100%',
320
+ zIndex: 999999,
321
+ elevation: 999999,
322
+ },
323
+ scrim: {
324
+ position: 'absolute',
325
+ top: 0,
326
+ bottom: 0,
327
+ left: 0,
328
+ right: 0,
329
+ width: '100%',
330
+ height: '100%',
331
+ backgroundColor: 'rgba(0, 0, 0, 0.72)',
332
+ },
333
+ spotlightRing: {
334
+ position: 'absolute',
335
+ borderWidth: 2,
336
+ borderColor: '#818CF8', // Electric neon violet/indigo
337
+ backgroundColor: 'rgba(99, 102, 241, 0.18)',
338
+ shadowColor: '#818CF8',
339
+ shadowOpacity: 0.9,
340
+ shadowRadius: 12,
341
+ shadowOffset: { width: 0, height: 0 },
342
+ zIndex: 1000000,
343
+ elevation: 1000000,
344
+ },
345
+ tooltipCard: {
346
+ position: 'absolute',
347
+ left: 12,
348
+ right: 12,
349
+ backgroundColor: '#13182C', // Luxurious Deep Space Navy Indigo
350
+ borderRadius: 16,
351
+ paddingHorizontal: 16,
352
+ paddingTop: 14,
353
+ paddingBottom: 13,
354
+ shadowColor: '#000000',
355
+ shadowOpacity: 0.6,
356
+ shadowRadius: 20,
357
+ shadowOffset: { width: 0, height: 10 },
358
+ elevation: 24,
359
+ zIndex: 1000001,
360
+ borderWidth: 1.2,
361
+ borderColor: 'rgba(129, 140, 248, 0.45)', // Neon Indigo glowing border
362
+ },
363
+ pointerSvgTop: {
364
+ position: 'absolute',
365
+ top: -9,
366
+ zIndex: 1000002,
367
+ },
368
+ pointerSvgBottom: {
369
+ position: 'absolute',
370
+ bottom: -9,
371
+ zIndex: 1000002,
372
+ },
373
+ cardHeader: {
374
+ flexDirection: 'row',
375
+ alignItems: 'center',
376
+ justifyContent: 'space-between',
377
+ marginBottom: 10,
378
+ },
379
+ badgePill: {
380
+ flexDirection: 'row',
381
+ alignItems: 'center',
382
+ gap: 5,
383
+ backgroundColor: 'rgba(99, 102, 241, 0.22)',
384
+ paddingHorizontal: 9,
385
+ paddingVertical: 3.5,
386
+ borderRadius: 7,
387
+ borderWidth: 0.8,
388
+ borderColor: 'rgba(165, 180, 252, 0.35)',
389
+ },
390
+ badgeDot: {
391
+ width: 5,
392
+ height: 5,
393
+ borderRadius: 2.5,
394
+ backgroundColor: '#818CF8',
395
+ },
396
+ badgeText: {
397
+ fontFamily: AppFonts.interBold,
398
+ fontSize: 9.5,
399
+ color: '#E0E7FF',
400
+ letterSpacing: 0.6,
401
+ },
402
+ topActions: {
403
+ flexDirection: 'row',
404
+ alignItems: 'center',
405
+ gap: 6,
406
+ },
407
+ skipHeaderBtn: {
408
+ flexDirection: 'row',
409
+ alignItems: 'center',
410
+ gap: 4,
411
+ backgroundColor: 'rgba(255, 255, 255, 0.08)',
412
+ paddingHorizontal: 8,
413
+ paddingVertical: 3.5,
414
+ borderRadius: 6,
415
+ borderWidth: 0.8,
416
+ borderColor: 'rgba(255, 255, 255, 0.14)',
417
+ },
418
+ skipHeaderIcon: {
419
+ fontSize: 9.5,
420
+ },
421
+ skipHeaderText: {
422
+ fontFamily: AppFonts.interMedium,
423
+ fontSize: 10.5,
424
+ color: '#CBD5E1',
425
+ },
426
+ closeBtn: {
427
+ width: 22,
428
+ height: 22,
429
+ borderRadius: 11,
430
+ backgroundColor: 'rgba(255, 255, 255, 0.08)',
431
+ alignItems: 'center',
432
+ justifyContent: 'center',
433
+ borderWidth: 0.8,
434
+ borderColor: 'rgba(255, 255, 255, 0.14)',
435
+ },
436
+ contentSection: {
437
+ marginBottom: 12,
438
+ },
439
+ titleRow: {
440
+ flexDirection: 'row',
441
+ alignItems: 'center',
442
+ gap: 8,
443
+ marginBottom: 6,
444
+ },
445
+ iconContainer: {
446
+ width: 28,
447
+ height: 28,
448
+ borderRadius: 7,
449
+ backgroundColor: 'rgba(99, 102, 241, 0.28)',
450
+ borderWidth: 0.8,
451
+ borderColor: 'rgba(165, 180, 252, 0.25)',
452
+ alignItems: 'center',
453
+ justifyContent: 'center',
454
+ },
455
+ titleEmoji: {
456
+ fontSize: 15,
457
+ },
458
+ titleText: {
459
+ flex: 1,
460
+ fontFamily: AppFonts.interBold,
461
+ fontSize: 15,
462
+ color: '#FFFFFF',
463
+ letterSpacing: -0.2,
464
+ },
465
+ descriptionText: {
466
+ fontFamily: AppFonts.interRegular,
467
+ fontSize: 12.5,
468
+ color: '#CBD5E1', // Clean slate-300
469
+ lineHeight: 18.5,
470
+ },
471
+ footerRow: {
472
+ flexDirection: 'row',
473
+ alignItems: 'center',
474
+ justifyContent: 'space-between',
475
+ paddingTop: 10,
476
+ borderTopWidth: 1,
477
+ borderTopColor: 'rgba(255, 255, 255, 0.12)',
478
+ marginBottom: 10,
479
+ },
480
+ dotsContainer: {
481
+ flexDirection: 'row',
482
+ alignItems: 'center',
483
+ gap: 5,
484
+ },
485
+ dot: {
486
+ width: 6,
487
+ height: 6,
488
+ borderRadius: 3,
489
+ backgroundColor: 'rgba(255, 255, 255, 0.2)',
490
+ },
491
+ dotActive: {
492
+ width: 18,
493
+ height: 6,
494
+ borderRadius: 3,
495
+ backgroundColor: '#818CF8', // Neon active pill
496
+ },
497
+ btnGroup: {
498
+ flexDirection: 'row',
499
+ alignItems: 'center',
500
+ gap: 8,
501
+ },
502
+ backBtn: {
503
+ paddingHorizontal: 11,
504
+ paddingVertical: 7,
505
+ borderRadius: 8,
506
+ backgroundColor: 'rgba(255, 255, 255, 0.08)',
507
+ borderWidth: 0.8,
508
+ borderColor: 'rgba(255, 255, 255, 0.14)',
509
+ },
510
+ backBtnText: {
511
+ fontFamily: AppFonts.interMedium,
512
+ fontSize: 12,
513
+ color: '#E0E7FF',
514
+ },
515
+ nextBtn: {
516
+ backgroundColor: '#6366F1', // Royal Indigo
517
+ paddingHorizontal: 16,
518
+ paddingVertical: 7.5,
519
+ borderRadius: 8,
520
+ shadowColor: '#6366F1',
521
+ shadowOpacity: 0.45,
522
+ shadowRadius: 6,
523
+ shadowOffset: { width: 0, height: 2 },
524
+ },
525
+ nextBtnFinal: {
526
+ backgroundColor: '#10B981', // Emerald green
527
+ shadowColor: '#10B981',
528
+ },
529
+ nextBtnText: {
530
+ fontFamily: AppFonts.interBold,
531
+ fontSize: 12.5,
532
+ color: '#FFFFFF',
533
+ },
534
+ dontShowRow: {
535
+ flexDirection: 'row',
536
+ alignItems: 'center',
537
+ gap: 6,
538
+ alignSelf: 'flex-start',
539
+ },
540
+ checkbox: {
541
+ width: 14,
542
+ height: 14,
543
+ borderRadius: 3.5,
544
+ borderWidth: 1.2,
545
+ borderColor: 'rgba(165, 180, 252, 0.5)',
546
+ backgroundColor: 'transparent',
547
+ alignItems: 'center',
548
+ justifyContent: 'center',
549
+ },
550
+ checkboxActive: {
551
+ backgroundColor: '#6366F1',
552
+ borderColor: '#6366F1',
553
+ },
554
+ dontShowText: {
555
+ fontFamily: AppFonts.interRegular,
556
+ fontSize: 10.5,
557
+ color: '#94A3B8',
558
+ },
559
+ });
560
+ export default FirstTimeWalkthroughModal;
@@ -14,7 +14,7 @@ import { getTelemetryConsentStatus } from '../../helpers/telemetry';
14
14
  import { UpdateAvailableModal } from './UpdateAvailableModal';
15
15
  import { WhiteBackNavigation, TrashIcon, SettingsIcon, CloseWhite, ClockIcon, SizeIcon, AppleIcon, AndroidIcon, NpmIcon, ResetIcon, } from '../NetworkIcons';
16
16
  const InspectorHeader = React.memo(() => {
17
- const { modalHeightPercent, appIcon, selected, setSelected, selectedEvent, setSelectedEvent, selectedLog, setSelectedLog, selectedReduxSlice, setSelectedReduxSlice, selectedReduxAction, setSelectedReduxAction, reduxState, reduxLastActionMap, showHeaderInfo, setShowHeaderInfo, updateAvailable, latestNpmVersion, clearAnim, activePulseAnim, unreadPulseAnim, runClearAllWithAnimation, settingsPage, setSettingsPage, resetToDefaults, closeModal, detailTitle, activeTab, environment, visible, selectedCrash, setSelectedCrash, } = useInspector();
17
+ const { modalHeightPercent, appIcon, selected, setSelected, selectedEvent, setSelectedEvent, selectedLog, setSelectedLog, selectedReduxSlice, setSelectedReduxSlice, selectedReduxAction, setSelectedReduxAction, reduxState, reduxLastActionMap, showHeaderInfo, setShowHeaderInfo, updateAvailable, latestNpmVersion, clearAnim, activePulseAnim, unreadPulseAnim, runClearAllWithAnimation, settingsPage, setSettingsPage, resetToDefaults, closeModal, detailTitle, activeTab, environment, visible, selectedCrash, setSelectedCrash, deviceInfo, } = useInspector();
18
18
  const [showUpdateModal, setShowUpdateModal] = React.useState(false);
19
19
  const [isTelemetryActive, setIsTelemetryActive] = React.useState(false);
20
20
  const telemetryPulseAnim = React.useRef(new Animated.Value(1)).current;
@@ -264,38 +264,44 @@ const InspectorHeader = React.memo(() => {
264
264
  </Pressable>)}
265
265
  </View>
266
266
 
267
- {/* OS & NPM Version Representation */}
267
+ {/* OS & NPM Version Common Chip Bar */}
268
268
  <View style={{
269
269
  flexDirection: 'row',
270
270
  alignItems: 'center',
271
271
  gap: 5,
272
272
  minWidth: 0,
273
273
  }}>
274
+ {/* Unified Platform & Build Chip */}
274
275
  <View style={{
275
276
  flexDirection: 'row',
276
277
  alignItems: 'center',
277
- backgroundColor: `${AppColors.white}1F`,
278
- borderRadius: 5,
279
- paddingHorizontal: 6,
280
- paddingVertical: 2,
281
- gap: 4,
278
+ backgroundColor: 'rgba(255, 255, 255, 0.16)',
279
+ borderRadius: 6,
280
+ paddingHorizontal: 6.5,
281
+ paddingVertical: 2.5,
282
+ gap: 4.5,
282
283
  borderWidth: 1,
283
- borderColor: `${AppColors.white}2E`,
284
+ borderColor: 'rgba(255, 255, 255, 0.28)',
284
285
  flexShrink: 0,
285
286
  }}>
286
- {Platform.OS === 'ios' ? (<AppleIcon color={`${AppColors.white}E6`} size={10}/>) : (<AndroidIcon color={`${AppColors.white}E6`} size={10}/>)}
287
+ {Platform.OS === 'ios' ? (<AppleIcon color="#FFFFFF" size={10.5}/>) : (<AndroidIcon color="#FFFFFF" size={10.5}/>)}
287
288
  <Text style={{
288
- fontFamily: AppFonts.interMedium,
289
+ fontFamily: AppFonts.interBold,
289
290
  fontSize: 9.5,
290
- color: `${AppColors.white}EB`,
291
+ color: '#FFFFFF',
291
292
  letterSpacing: 0.1,
292
293
  }} numberOfLines={1}>
293
294
  {Platform.OS === 'ios'
294
- ? `iOS ${Platform.Version}`
295
- : `Android ${Platform.Version}`}
295
+ ? `iOS ${String(deviceInfo?.osVersion || Platform.Version).replace(/^(ios\s*)+/i, '').trim()}${deviceInfo?.buildNumber || deviceInfo?.appVersion
296
+ ? ` (${deviceInfo.buildNumber || deviceInfo.appVersion})`
297
+ : ''}`
298
+ : `Android ${String(deviceInfo?.osVersion || Platform.Version).replace(/^(android\s*)+/i, '').trim()}${deviceInfo?.buildNumber || deviceInfo?.appVersion
299
+ ? ` (${deviceInfo.buildNumber || deviceInfo.appVersion})`
300
+ : ''}`}
296
301
  </Text>
297
302
  </View>
298
303
 
304
+ {/* Unified NPM Version Chip */}
299
305
  <Pressable onPress={() => {
300
306
  if (updateAvailable) {
301
307
  setShowUpdateModal(true);
@@ -304,26 +310,23 @@ const InspectorHeader = React.memo(() => {
304
310
  Linking.openURL('https://www.npmjs.com/package/react-native-inapp-inspector').catch(() => { });
305
311
  }
306
312
  }} style={{
307
- backgroundColor: '#FFFFFF',
308
- borderRadius: 5,
309
- paddingHorizontal: 6,
310
- paddingVertical: 2,
313
+ backgroundColor: 'rgba(255, 255, 255, 0.16)',
314
+ borderRadius: 6,
315
+ paddingHorizontal: 6.5,
316
+ paddingVertical: 2.5,
311
317
  flexDirection: 'row',
312
318
  alignItems: 'center',
313
319
  gap: 4,
320
+ borderWidth: 1,
321
+ borderColor: 'rgba(255, 255, 255, 0.28)',
314
322
  flexShrink: 0,
315
- shadowColor: '#000000',
316
- shadowOffset: { width: 0, height: 1 },
317
- shadowOpacity: 0.15,
318
- shadowRadius: 2,
319
- elevation: 2,
320
323
  }}>
321
- <NpmIcon size={11} color="#CB3837"/>
324
+ <NpmIcon size={11} color="#FF6B6B"/>
322
325
  <Text style={{
323
326
  fontFamily: AppFonts.interBold,
324
327
  fontSize: 9.5,
325
- color: '#CB3837',
326
- letterSpacing: 0.2,
328
+ color: '#FFFFFF',
329
+ letterSpacing: 0.15,
327
330
  }} numberOfLines={1}>
328
331
  v{LIB_VERSION}
329
332
  </Text>