react-native-inapp-inspector 1.1.6 → 1.1.9
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 +42 -3
- package/dist/commonjs/components/LogCard.js +14 -1
- package/dist/commonjs/components/NetworkIcons.d.ts +1 -0
- package/dist/commonjs/components/NetworkIcons.js +7 -0
- package/dist/commonjs/constants/version.d.ts +1 -1
- package/dist/commonjs/constants/version.js +1 -1
- package/dist/commonjs/helpers/index.d.ts +1 -0
- package/dist/commonjs/helpers/index.js +12 -1
- package/dist/commonjs/helpers/settingsStore.d.ts +1 -0
- package/dist/commonjs/index.js +188 -19
- package/dist/commonjs/styles/index.d.ts +3 -0
- package/dist/commonjs/styles/index.js +9 -6
- package/dist/esm/components/LogCard.js +15 -2
- package/dist/esm/components/NetworkIcons.d.ts +1 -0
- package/dist/esm/components/NetworkIcons.js +5 -0
- package/dist/esm/constants/version.d.ts +1 -1
- package/dist/esm/constants/version.js +1 -1
- package/dist/esm/helpers/index.d.ts +1 -0
- package/dist/esm/helpers/index.js +10 -0
- package/dist/esm/helpers/settingsStore.d.ts +1 -0
- package/dist/esm/index.js +190 -21
- package/dist/esm/styles/index.d.ts +3 -0
- package/dist/esm/styles/index.js +9 -6
- package/example/App.tsx +4 -3
- package/example/package-lock.json +4 -4
- package/example/package.json +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -125,6 +125,32 @@ If no `storage` prop is passed, Android will fall back to an in-memory store (se
|
|
|
125
125
|
|
|
126
126
|
---
|
|
127
127
|
|
|
128
|
+
## Navigation & Screen Tracking
|
|
129
|
+
|
|
130
|
+
To group network requests, console logs, and analytics events by the specific navigation screen where they occurred, the inspector automatically hooks into React Navigation context.
|
|
131
|
+
|
|
132
|
+
If you mount `<NetworkInspector />` globally at the root of your application (outside of the `<NavigationContainer>`), it won't have access to React Navigation's context. To enable accurate screen tracking in this setup, create a navigation ref and pass it to the `navigationRef` prop:
|
|
133
|
+
|
|
134
|
+
```tsx
|
|
135
|
+
import { NavigationContainer, createNavigationContainerRef } from '@react-navigation/native';
|
|
136
|
+
import NetworkInspector from 'react-native-inapp-inspector';
|
|
137
|
+
|
|
138
|
+
const navigationRef = createNavigationContainerRef();
|
|
139
|
+
|
|
140
|
+
const App = () => {
|
|
141
|
+
return (
|
|
142
|
+
<>
|
|
143
|
+
<NavigationContainer ref={navigationRef}>
|
|
144
|
+
{/* Navigators / Screens */}
|
|
145
|
+
</NavigationContainer>
|
|
146
|
+
<NetworkInspector navigationRef={navigationRef} />
|
|
147
|
+
</>
|
|
148
|
+
);
|
|
149
|
+
};
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
128
154
|
## Network Logging
|
|
129
155
|
|
|
130
156
|
`setupNetworkLogger()` patches global `fetch`, the default axios instance, and future axios instances created with `axios.create()`.
|
|
@@ -272,8 +298,11 @@ import {ErrorBoundary} from 'react-native-inapp-inspector';
|
|
|
272
298
|
| `clearAnalyticsEvents()` | function | Clears captured analytics events. |
|
|
273
299
|
| `subscribeAnalyticsEvents(callback)` | function | Subscribes to analytics event updates and returns an unsubscribe function. |
|
|
274
300
|
| `connectReduxStore(store)` | function | Connects a Redux store for live state and action inspection. |
|
|
301
|
+
| `inspectorReduxMiddleware` | middleware | Redux middleware to capture actions dispatched from thunks/sagas. |
|
|
275
302
|
| `getReduxState()` | function | Returns the latest captured Redux state. |
|
|
276
303
|
| `subscribeReduxState(callback)` | function | Subscribes to Redux state updates and returns an unsubscribe function. |
|
|
304
|
+
| `getActionHistory()` | function | Returns the recent dispatched Redux actions. |
|
|
305
|
+
| `clearActionHistory()` | function | Clears the Redux action history. |
|
|
277
306
|
| `WebView` | component | Instrumented WebView wrapper. |
|
|
278
307
|
| `getWebViewLogs()` | function | Returns captured WebView console logs. |
|
|
279
308
|
| `getWebViewNavHistory()` | function | Returns captured WebView navigation history. |
|
|
@@ -300,11 +329,21 @@ npm run ios
|
|
|
300
329
|
|
|
301
330
|
---
|
|
302
331
|
|
|
303
|
-
##
|
|
332
|
+
## Contributing 🤝
|
|
333
|
+
|
|
334
|
+
Contributions are welcome! Please check out our [Contributing Guidelines](CONTRIBUTING.md) to learn how to get started, set up the development environment, or request features.
|
|
335
|
+
|
|
336
|
+
---
|
|
337
|
+
|
|
338
|
+
## Support & Sponsoring 💖
|
|
339
|
+
|
|
340
|
+
This library is a completely free, open-source utility maintained in the author's spare time. If this tool has saved you or your team hours of debugging, please consider supporting its continuous development.
|
|
341
|
+
|
|
342
|
+
Sponsoring helps prioritize your bug fixes, maintain compatibility with new React Native versions, and support new features.
|
|
304
343
|
|
|
305
|
-
|
|
344
|
+
👉 **[Sponsor @vengatmacuser on GitHub Sponsors](https://github.com/sponsors/vengatmacuser)**
|
|
306
345
|
|
|
307
|
-
[](https://github.com/sponsors/vengatmacuser)
|
|
346
|
+
[](https://github.com/sponsors/vengatmacuser)
|
|
308
347
|
|
|
309
348
|
---
|
|
310
349
|
|
|
@@ -43,6 +43,7 @@ const AppColors_1 = require("../styles/AppColors");
|
|
|
43
43
|
const constants_1 = require("../constants");
|
|
44
44
|
const helpers_1 = require("../helpers");
|
|
45
45
|
const NetworkIcons_1 = require("./NetworkIcons");
|
|
46
|
+
const AppFonts_1 = require("../styles/AppFonts");
|
|
46
47
|
const styles_1 = __importDefault(require("../styles"));
|
|
47
48
|
const HighlightText_1 = __importDefault(require("./HighlightText"));
|
|
48
49
|
const TouchableScale_1 = __importDefault(require("./TouchableScale"));
|
|
@@ -74,6 +75,8 @@ const LogCard = react_1.default.memo(function LogCard({ item, onPress, timelineM
|
|
|
74
75
|
}
|
|
75
76
|
}, [isNew]);
|
|
76
77
|
const path = (0, helpers_1.getPath)(item.url);
|
|
78
|
+
const baseUrl = (0, helpers_1.getBaseUrl)(item.url) || item.url;
|
|
79
|
+
const showPathRow = baseUrl !== item.url && path !== '/';
|
|
77
80
|
const triggeredAt = (0, helpers_1.formatDateTime)(item.startTime);
|
|
78
81
|
const isJson = item.url.split('?')[0].toLowerCase().endsWith('.json');
|
|
79
82
|
return (<TouchableScale_1.default onPress={onPress} style={[
|
|
@@ -102,7 +105,7 @@ const LogCard = react_1.default.memo(function LogCard({ item, onPress, timelineM
|
|
|
102
105
|
</react_native_1.Text>
|
|
103
106
|
</react_native_1.View>
|
|
104
107
|
|
|
105
|
-
<HighlightText_1.default text={
|
|
108
|
+
<HighlightText_1.default text={baseUrl} search={searchStr} style={styles_1.default.urlPathText} highlightStyle={styles_1.default.highlight} numberOfLines={0}/>
|
|
106
109
|
|
|
107
110
|
{isJson && (<react_native_1.View style={[
|
|
108
111
|
styles_1.default.chip,
|
|
@@ -135,6 +138,16 @@ const LogCard = react_1.default.memo(function LogCard({ item, onPress, timelineM
|
|
|
135
138
|
</react_native_1.View>)}
|
|
136
139
|
</react_native_1.View>
|
|
137
140
|
|
|
141
|
+
{showPathRow && (<react_native_1.View style={{ flexDirection: 'row', alignItems: 'flex-start', marginTop: 3, marginBottom: 5, paddingLeft: 30, gap: 6 }}>
|
|
142
|
+
<react_native_1.Text style={{ color: AppColors_1.AppColors.grayTextWeak, fontSize: 9, fontFamily: AppFonts_1.AppFonts.interBold, letterSpacing: 0.5, marginTop: 2.5 }}>PATH</react_native_1.Text>
|
|
143
|
+
<HighlightText_1.default text={path} search={searchStr} style={{
|
|
144
|
+
fontFamily: AppFonts_1.AppFonts.Sfprotext || 'System',
|
|
145
|
+
fontSize: 12,
|
|
146
|
+
color: AppColors_1.AppColors.grayText,
|
|
147
|
+
flex: 1,
|
|
148
|
+
}} highlightStyle={styles_1.default.highlight} numberOfLines={0}/>
|
|
149
|
+
</react_native_1.View>)}
|
|
150
|
+
|
|
138
151
|
<react_native_1.View style={styles_1.default.cardBottomRow}>
|
|
139
152
|
<react_native_1.View style={styles_1.default.cardDateRow}>
|
|
140
153
|
<NetworkIcons_1.CalendarIcon color={AppColors_1.AppColors.grayTextWeak} size={11}/>
|
|
@@ -49,3 +49,4 @@ export declare const InfoCircleIcon: ({ color, size, }: any) => React.JSX.Elemen
|
|
|
49
49
|
export declare const WarningTriangleIcon: ({ color, size, }: any) => React.JSX.Element;
|
|
50
50
|
export declare const ErrorCircleIcon: ({ color, size, }: any) => React.JSX.Element;
|
|
51
51
|
export declare const TrendingUpIcon: ({ color, size, }: any) => React.JSX.Element;
|
|
52
|
+
export declare const MotionIcon: ({ color, size, }: any) => React.JSX.Element;
|
|
@@ -37,6 +37,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
37
37
|
};
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
39
|
exports.TrendingUpIcon = exports.ErrorCircleIcon = exports.WarningTriangleIcon = exports.InfoCircleIcon = exports.UserIcon = exports.LayersIcon = exports.WipeIcon = exports.FolderIcon = exports.SettingsIcon = exports.EyeIcon = exports.JsIcon = exports.CssIcon = exports.HtmlIcon = exports.BrandSquareIcon = exports.BrandCircleIcon = exports.MoonIcon = exports.SunIcon = exports.DebugIcon = exports.InsightsIcon = exports.AnalyticsIcon = exports.WhiteBackNavigation = exports.CloseWhite = exports.DownloadIcon = exports.FilterIcon = exports.ChevronIcon = exports.SortArrowIcon = exports.GlobeIcon = exports.DiffIcon = exports.SignalIcon = exports.ExportIcon = exports.HeaderPauseIcon = exports.TrashIcon = exports.FailIcon = exports.CheckIcon = exports.TerminalIcon = exports.FetchIcon = exports.CopyIcon = exports.HeadersIcon = exports.ResponseIcon = exports.RequestIcon = exports.SizeIcon = exports.StatusIcon = exports.CalendarIcon = exports.ClockIcon = exports.ClearIcon = exports.SearchIcon = exports.ExpandCollapseIcon = exports.ScreenIcon = exports.MapPinIcon = exports.EmptyRadarIcon = void 0;
|
|
40
|
+
exports.MotionIcon = void 0;
|
|
40
41
|
const react_1 = __importDefault(require("react"));
|
|
41
42
|
const react_native_svg_1 = __importStar(require("react-native-svg"));
|
|
42
43
|
// Stylesheet
|
|
@@ -386,3 +387,9 @@ const TrendingUpIcon = ({ color = AppColors_1.AppColors.grayTextWeak, size = 12,
|
|
|
386
387
|
</react_native_svg_1.default>);
|
|
387
388
|
};
|
|
388
389
|
exports.TrendingUpIcon = TrendingUpIcon;
|
|
390
|
+
const MotionIcon = ({ color = AppColors_1.AppColors.grayTextWeak, size = 14, }) => {
|
|
391
|
+
return (<react_native_svg_1.default width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
392
|
+
<react_native_svg_1.Path d="M5 3l14 9-14 9V3z" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
|
|
393
|
+
</react_native_svg_1.default>);
|
|
394
|
+
};
|
|
395
|
+
exports.MotionIcon = MotionIcon;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const LIB_VERSION = "1.1.
|
|
1
|
+
export declare const LIB_VERSION = "1.1.9";
|
|
@@ -3,4 +3,4 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.LIB_VERSION = void 0;
|
|
4
4
|
// AUTO-GENERATED FILE — do not edit by hand.
|
|
5
5
|
// Regenerated from package.json on every build by scripts/gen-version.js.
|
|
6
|
-
exports.LIB_VERSION = '1.1.
|
|
6
|
+
exports.LIB_VERSION = '1.1.9';
|
|
@@ -6,6 +6,7 @@ export declare const getDurationColor: (duration: number | null) => string;
|
|
|
6
6
|
export declare const getSize: (data: unknown) => string;
|
|
7
7
|
export declare const copyToClipboard: (value: unknown, label: string) => void;
|
|
8
8
|
export declare const getPath: (url: string) => string;
|
|
9
|
+
export declare const getBaseUrl: (url: string) => string;
|
|
9
10
|
export declare const getCurlCommand: (log: NetworkLog) => string;
|
|
10
11
|
export declare const getFetchCommand: (log: NetworkLog) => string;
|
|
11
12
|
export declare const deduplicateLogs: (raw: NetworkLog[]) => NetworkLog[];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.formatDateTimeToAnalytics = exports.isAllValuesEmpty = exports.getLocalizedFilePathWithSlash = exports.getLocalizedFilePath = exports.formatDisplayUrl = exports.getDiff = exports.flattenObject = exports.getNavigationInfo = exports.escapeRegex = exports.deduplicateLogs = exports.getFetchCommand = exports.getCurlCommand = exports.getPath = exports.copyToClipboard = exports.getSize = exports.getDurationColor = exports.getStatusColor = exports.formatDateTime = exports.getDomainColor = void 0;
|
|
3
|
+
exports.formatDateTimeToAnalytics = exports.isAllValuesEmpty = exports.getLocalizedFilePathWithSlash = exports.getLocalizedFilePath = exports.formatDisplayUrl = exports.getDiff = exports.flattenObject = exports.getNavigationInfo = exports.escapeRegex = exports.deduplicateLogs = exports.getFetchCommand = exports.getCurlCommand = exports.getBaseUrl = exports.getPath = exports.copyToClipboard = exports.getSize = exports.getDurationColor = exports.getStatusColor = exports.formatDateTime = exports.getDomainColor = void 0;
|
|
4
4
|
const react_native_1 = require("react-native");
|
|
5
5
|
// Stylesheet
|
|
6
6
|
const AppColors_1 = require("../styles/AppColors");
|
|
@@ -83,6 +83,17 @@ const getPath = (url) => {
|
|
|
83
83
|
}
|
|
84
84
|
};
|
|
85
85
|
exports.getPath = getPath;
|
|
86
|
+
const getBaseUrl = (url) => {
|
|
87
|
+
try {
|
|
88
|
+
const u = new URL(url);
|
|
89
|
+
return `${u.protocol}//${u.host}`;
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
const match = url.match(/^(https?:\/\/[^/]+)/);
|
|
93
|
+
return match ? match[1] : '';
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
exports.getBaseUrl = getBaseUrl;
|
|
86
97
|
const getCurlCommand = (log) => {
|
|
87
98
|
let cmd = `curl -X ${log.method} "${log.url}"`;
|
|
88
99
|
if (log.requestHeaders) {
|
|
@@ -6,6 +6,7 @@ export declare function setCustomStorage(storage: InspectorStorage | null): void
|
|
|
6
6
|
export interface PersistedSettings {
|
|
7
7
|
isDark?: boolean;
|
|
8
8
|
modalHeightPercent?: number;
|
|
9
|
+
modalAnimationType?: string;
|
|
9
10
|
tabVisibility?: Record<string, boolean>;
|
|
10
11
|
defaultTab?: string;
|
|
11
12
|
maxNetworkLogs?: number;
|
package/dist/commonjs/index.js
CHANGED
|
@@ -152,7 +152,7 @@ const NavigationTracker = ({ onStateChange }) => {
|
|
|
152
152
|
const animateNextLayout = () => {
|
|
153
153
|
react_native_1.LayoutAnimation.configureNext(react_native_1.LayoutAnimation.Presets.easeInEaseOut);
|
|
154
154
|
};
|
|
155
|
-
const NetworkInspector = ({ enabled = true, storage, }) => {
|
|
155
|
+
const NetworkInspector = ({ enabled = true, storage, navigationRef, }) => {
|
|
156
156
|
// Set custom storage synchronously during render phase
|
|
157
157
|
(0, settingsStore_1.setCustomStorage)(storage || null);
|
|
158
158
|
const [isDark, setIsDark] = (0, react_1.useState)(false);
|
|
@@ -163,6 +163,8 @@ const NetworkInspector = ({ enabled = true, storage, }) => {
|
|
|
163
163
|
const [reduxLastActionMap, setReduxLastActionMap] = (0, react_1.useState)({});
|
|
164
164
|
// Inspector panel height as a percentage of the screen (configurable in Settings).
|
|
165
165
|
const [modalHeightPercent, setModalHeightPercent] = (0, react_1.useState)(90);
|
|
166
|
+
const [modalAnimationType, setModalAnimationType] = (0, react_1.useState)('slide');
|
|
167
|
+
const headerTopPadding = react_native_1.Platform.OS === 'ios' && modalHeightPercent >= 95 ? 44 : 0;
|
|
166
168
|
const [expandedReducers, setExpandedReducers] = (0, react_1.useState)({});
|
|
167
169
|
const [logs, setLogs] = (0, react_1.useState)([]);
|
|
168
170
|
const [visible, setVisible] = (0, react_1.useState)(false);
|
|
@@ -290,6 +292,7 @@ const NetworkInspector = ({ enabled = true, storage, }) => {
|
|
|
290
292
|
setIsDark(false);
|
|
291
293
|
(0, styles_1.toggleGlobalTheme)(false);
|
|
292
294
|
setModalHeightPercent(90);
|
|
295
|
+
setModalAnimationType('slide');
|
|
293
296
|
setTabVisibility({
|
|
294
297
|
insights: true,
|
|
295
298
|
apis: true,
|
|
@@ -327,6 +330,8 @@ const NetworkInspector = ({ enabled = true, storage, }) => {
|
|
|
327
330
|
}
|
|
328
331
|
if (saved.modalHeightPercent != null)
|
|
329
332
|
setModalHeightPercent(saved.modalHeightPercent);
|
|
333
|
+
if (saved.modalAnimationType)
|
|
334
|
+
setModalAnimationType(saved.modalAnimationType);
|
|
330
335
|
if (saved.tabVisibility)
|
|
331
336
|
setTabVisibility(prev => ({
|
|
332
337
|
...prev,
|
|
@@ -381,6 +386,7 @@ const NetworkInspector = ({ enabled = true, storage, }) => {
|
|
|
381
386
|
(0, settingsStore_1.saveSettings)({
|
|
382
387
|
isDark,
|
|
383
388
|
modalHeightPercent,
|
|
389
|
+
modalAnimationType,
|
|
384
390
|
tabVisibility,
|
|
385
391
|
defaultTab,
|
|
386
392
|
maxNetworkLogs,
|
|
@@ -396,6 +402,7 @@ const NetworkInspector = ({ enabled = true, storage, }) => {
|
|
|
396
402
|
}, [
|
|
397
403
|
isDark,
|
|
398
404
|
modalHeightPercent,
|
|
405
|
+
modalAnimationType,
|
|
399
406
|
tabVisibility,
|
|
400
407
|
defaultTab,
|
|
401
408
|
maxNetworkLogs,
|
|
@@ -538,6 +545,36 @@ const NetworkInspector = ({ enabled = true, storage, }) => {
|
|
|
538
545
|
currentRouteRef.current = (0, helpers_1.getNavigationInfo)(navState);
|
|
539
546
|
}
|
|
540
547
|
}, [navState]);
|
|
548
|
+
(0, react_1.useEffect)(() => {
|
|
549
|
+
if (!navigationRef)
|
|
550
|
+
return;
|
|
551
|
+
const updateState = () => {
|
|
552
|
+
try {
|
|
553
|
+
if (typeof navigationRef.isReady === 'function' && navigationRef.isReady()) {
|
|
554
|
+
const state = navigationRef.getRootState();
|
|
555
|
+
if (state) {
|
|
556
|
+
setNavState(state);
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
catch (err) {
|
|
561
|
+
// Safe check
|
|
562
|
+
}
|
|
563
|
+
};
|
|
564
|
+
// Initialize state
|
|
565
|
+
updateState();
|
|
566
|
+
// Listen to changes
|
|
567
|
+
const unsubscribe = typeof navigationRef.addListener === 'function'
|
|
568
|
+
? navigationRef.addListener('state', () => {
|
|
569
|
+
updateState();
|
|
570
|
+
})
|
|
571
|
+
: null;
|
|
572
|
+
return () => {
|
|
573
|
+
if (unsubscribe) {
|
|
574
|
+
unsubscribe();
|
|
575
|
+
}
|
|
576
|
+
};
|
|
577
|
+
}, [navigationRef]);
|
|
541
578
|
const logRouteMapRef = (0, react_1.useRef)(new Map());
|
|
542
579
|
const prevLogIdsRef = (0, react_1.useRef)(new Set());
|
|
543
580
|
const [newLogIds, setNewLogIds] = (0, react_1.useState)(new Set());
|
|
@@ -1362,7 +1399,7 @@ const NetworkInspector = ({ enabled = true, storage, }) => {
|
|
|
1362
1399
|
return (<react_native_1.View style={{ flex: 1, backgroundColor: AppColors_1.AppColors.grayBackground }}>
|
|
1363
1400
|
{/* Settings Header with back button */}
|
|
1364
1401
|
<react_native_linear_gradient_1.default colors={[AppColors_1.AppColors.purple, '#6B4EFF']} start={{ x: 0, y: 0 }} end={{ x: 1, y: 0 }} style={styles_1.default.headerGradient}>
|
|
1365
|
-
<react_native_1.
|
|
1402
|
+
<react_native_1.View style={{ paddingTop: headerTopPadding, width: '100%' }}>
|
|
1366
1403
|
<react_native_1.View style={[styles_1.default.header, { paddingHorizontal: 16, gap: 12 }]}>
|
|
1367
1404
|
<TouchableScale_1.default onPress={() => {
|
|
1368
1405
|
animateNextLayout();
|
|
@@ -1411,7 +1448,7 @@ const NetworkInspector = ({ enabled = true, storage, }) => {
|
|
|
1411
1448
|
</react_native_1.Text>
|
|
1412
1449
|
</react_native_1.View>
|
|
1413
1450
|
</react_native_1.View>
|
|
1414
|
-
</react_native_1.
|
|
1451
|
+
</react_native_1.View>
|
|
1415
1452
|
</react_native_linear_gradient_1.default>
|
|
1416
1453
|
|
|
1417
1454
|
<react_native_1.ScrollView style={{ flex: 1 }} contentContainerStyle={{ padding: 16, gap: 12 }}>
|
|
@@ -1838,6 +1875,90 @@ const NetworkInspector = ({ enabled = true, storage, }) => {
|
|
|
1838
1875
|
</react_native_1.View>
|
|
1839
1876
|
</react_native_1.View>
|
|
1840
1877
|
|
|
1878
|
+
{/* Divider */}
|
|
1879
|
+
<react_native_1.View style={{
|
|
1880
|
+
height: 1,
|
|
1881
|
+
backgroundColor: AppColors_1.AppColors.dividerColor,
|
|
1882
|
+
}}/>
|
|
1883
|
+
|
|
1884
|
+
{/* Modal Animation */}
|
|
1885
|
+
<react_native_1.View style={{
|
|
1886
|
+
paddingVertical: 12,
|
|
1887
|
+
paddingHorizontal: 14,
|
|
1888
|
+
}}>
|
|
1889
|
+
<react_native_1.View style={{
|
|
1890
|
+
flexDirection: 'row',
|
|
1891
|
+
alignItems: 'center',
|
|
1892
|
+
gap: 8,
|
|
1893
|
+
}}>
|
|
1894
|
+
<react_native_1.View style={{
|
|
1895
|
+
width: 20,
|
|
1896
|
+
height: 20,
|
|
1897
|
+
borderRadius: 6,
|
|
1898
|
+
backgroundColor: AppColors_1.AppColors.purpleShade50,
|
|
1899
|
+
borderWidth: 1,
|
|
1900
|
+
borderColor: 'rgba(104,75,155,0.2)',
|
|
1901
|
+
alignItems: 'center',
|
|
1902
|
+
justifyContent: 'center',
|
|
1903
|
+
}}>
|
|
1904
|
+
<NetworkIcons_1.MotionIcon color={AppColors_1.AppColors.purple} size={11}/>
|
|
1905
|
+
</react_native_1.View>
|
|
1906
|
+
<react_native_1.View style={{ flex: 1 }}>
|
|
1907
|
+
<react_native_1.Text style={{
|
|
1908
|
+
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
1909
|
+
fontSize: 13,
|
|
1910
|
+
color: AppColors_1.AppColors.primaryBlack,
|
|
1911
|
+
}}>
|
|
1912
|
+
Modal Animation
|
|
1913
|
+
</react_native_1.Text>
|
|
1914
|
+
<react_native_1.Text style={{
|
|
1915
|
+
fontFamily: AppFonts_1.AppFonts.interRegular,
|
|
1916
|
+
fontSize: 11,
|
|
1917
|
+
color: AppColors_1.AppColors.grayText,
|
|
1918
|
+
marginTop: 1,
|
|
1919
|
+
}}>
|
|
1920
|
+
How the inspector panel enters and exits the screen
|
|
1921
|
+
</react_native_1.Text>
|
|
1922
|
+
</react_native_1.View>
|
|
1923
|
+
</react_native_1.View>
|
|
1924
|
+
|
|
1925
|
+
{/* Segmented picker */}
|
|
1926
|
+
<react_native_1.View style={{
|
|
1927
|
+
flexDirection: 'row',
|
|
1928
|
+
backgroundColor: AppColors_1.AppColors.grayBackground,
|
|
1929
|
+
borderRadius: 8,
|
|
1930
|
+
padding: 2.5,
|
|
1931
|
+
marginTop: 10,
|
|
1932
|
+
borderWidth: 1,
|
|
1933
|
+
borderColor: AppColors_1.AppColors.dividerColor,
|
|
1934
|
+
}}>
|
|
1935
|
+
{([
|
|
1936
|
+
{ key: 'slide', label: 'Slide Up' },
|
|
1937
|
+
{ key: 'fade', label: 'Fade' },
|
|
1938
|
+
{ key: 'none', label: 'None' },
|
|
1939
|
+
]).map(opt => {
|
|
1940
|
+
const isActive = modalAnimationType === opt.key;
|
|
1941
|
+
return (<TouchableScale_1.default key={opt.key} onPress={() => setModalAnimationType(opt.key)} style={{
|
|
1942
|
+
flex: 1,
|
|
1943
|
+
paddingVertical: 6,
|
|
1944
|
+
alignItems: 'center',
|
|
1945
|
+
borderRadius: 6,
|
|
1946
|
+
backgroundColor: isActive
|
|
1947
|
+
? AppColors_1.AppColors.purple
|
|
1948
|
+
: 'transparent',
|
|
1949
|
+
}}>
|
|
1950
|
+
<react_native_1.Text style={{
|
|
1951
|
+
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
1952
|
+
fontSize: 11,
|
|
1953
|
+
color: isActive ? '#FFFFFF' : AppColors_1.AppColors.grayText,
|
|
1954
|
+
}}>
|
|
1955
|
+
{opt.label}
|
|
1956
|
+
</react_native_1.Text>
|
|
1957
|
+
</TouchableScale_1.default>);
|
|
1958
|
+
})}
|
|
1959
|
+
</react_native_1.View>
|
|
1960
|
+
</react_native_1.View>
|
|
1961
|
+
|
|
1841
1962
|
{/* Divider */}
|
|
1842
1963
|
<react_native_1.View style={{
|
|
1843
1964
|
height: 1,
|
|
@@ -2679,7 +2800,7 @@ const NetworkInspector = ({ enabled = true, storage, }) => {
|
|
|
2679
2800
|
}
|
|
2680
2801
|
return (<react_native_1.View style={{ flex: 1, backgroundColor: AppColors_1.AppColors.grayBackground }}>
|
|
2681
2802
|
<react_native_linear_gradient_1.default colors={[AppColors_1.AppColors.purple, '#6B4EFF']} start={{ x: 0, y: 0 }} end={{ x: 1, y: 0 }} style={styles_1.default.headerGradient}>
|
|
2682
|
-
<react_native_1.
|
|
2803
|
+
<react_native_1.View style={{ paddingTop: headerTopPadding, width: '100%' }}>
|
|
2683
2804
|
<react_native_1.View style={[styles_1.default.header, { paddingHorizontal: 16, gap: 12 }]}>
|
|
2684
2805
|
<TouchableScale_1.default onPress={goBackToMain} hitSlop={12} style={{
|
|
2685
2806
|
padding: 8,
|
|
@@ -2726,7 +2847,7 @@ const NetworkInspector = ({ enabled = true, storage, }) => {
|
|
|
2726
2847
|
</react_native_1.Text>
|
|
2727
2848
|
</react_native_1.View>) : null}
|
|
2728
2849
|
</react_native_1.View>
|
|
2729
|
-
</react_native_1.
|
|
2850
|
+
</react_native_1.View>
|
|
2730
2851
|
</react_native_linear_gradient_1.default>
|
|
2731
2852
|
{content}
|
|
2732
2853
|
</react_native_1.View>);
|
|
@@ -3563,7 +3684,7 @@ const NetworkInspector = ({ enabled = true, storage, }) => {
|
|
|
3563
3684
|
</TouchableScale_1.default>
|
|
3564
3685
|
</react_native_1.Animated.View>
|
|
3565
3686
|
|
|
3566
|
-
<react_native_1.Modal visible={visible} animationType=
|
|
3687
|
+
<react_native_1.Modal visible={visible} animationType={modalAnimationType} transparent>
|
|
3567
3688
|
{visible && (<ErrorBoundary_1.default onClose={closeModal}>
|
|
3568
3689
|
<react_native_1.View style={styles_1.default.modalBackdrop}>
|
|
3569
3690
|
<react_native_1.Pressable style={styles_1.default.modalBackdropPressable} onPress={closeModal}/>
|
|
@@ -3574,7 +3695,7 @@ const NetworkInspector = ({ enabled = true, storage, }) => {
|
|
|
3574
3695
|
<react_native_1.StatusBar translucent backgroundColor="transparent" barStyle="light-content"/>
|
|
3575
3696
|
|
|
3576
3697
|
<react_native_linear_gradient_1.default colors={[AppColors_1.AppColors.purple, '#6B4EFF']} style={styles_1.default.headerGradient}>
|
|
3577
|
-
<react_native_1.
|
|
3698
|
+
<react_native_1.View style={{ paddingTop: headerTopPadding, width: '100%' }}>
|
|
3578
3699
|
<react_native_1.View style={styles_1.default.header}>
|
|
3579
3700
|
<react_native_1.View style={[
|
|
3580
3701
|
styles_1.default.headerLeft,
|
|
@@ -3912,7 +4033,7 @@ const NetworkInspector = ({ enabled = true, storage, }) => {
|
|
|
3912
4033
|
</TouchableScale_1.default>
|
|
3913
4034
|
</react_native_1.View>
|
|
3914
4035
|
</react_native_1.View>
|
|
3915
|
-
</react_native_1.
|
|
4036
|
+
</react_native_1.View>
|
|
3916
4037
|
</react_native_linear_gradient_1.default>
|
|
3917
4038
|
|
|
3918
4039
|
{/* ─── Horizontal Scrollable Tab Bar inside Content ─── */}
|
|
@@ -4037,8 +4158,25 @@ const NetworkInspector = ({ enabled = true, storage, }) => {
|
|
|
4037
4158
|
? AppColors_1.AppColors.purple
|
|
4038
4159
|
: AppColors_1.AppColors.grayTextStrong} size={18}/>
|
|
4039
4160
|
</TouchableScale_1.default>
|
|
4040
|
-
<TouchableScale_1.default style={
|
|
4041
|
-
|
|
4161
|
+
<TouchableScale_1.default style={{
|
|
4162
|
+
flexDirection: 'row',
|
|
4163
|
+
alignItems: 'center',
|
|
4164
|
+
gap: 4,
|
|
4165
|
+
paddingHorizontal: 10,
|
|
4166
|
+
paddingVertical: 5,
|
|
4167
|
+
borderRadius: 8,
|
|
4168
|
+
backgroundColor: 'rgba(255,46,87,0.06)',
|
|
4169
|
+
borderWidth: 1,
|
|
4170
|
+
borderColor: 'rgba(255,46,87,0.15)',
|
|
4171
|
+
}} onPress={handleDelete} hitSlop={6}>
|
|
4172
|
+
<NetworkIcons_1.WipeIcon color={AppColors_1.AppColors.errorColor} size={13}/>
|
|
4173
|
+
<react_native_1.Text style={{
|
|
4174
|
+
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
4175
|
+
fontSize: 10.5,
|
|
4176
|
+
color: AppColors_1.AppColors.errorColor,
|
|
4177
|
+
}}>
|
|
4178
|
+
Clear
|
|
4179
|
+
</react_native_1.Text>
|
|
4042
4180
|
</TouchableScale_1.default>
|
|
4043
4181
|
</react_native_1.View>)}
|
|
4044
4182
|
</react_native_1.View>
|
|
@@ -4264,13 +4402,27 @@ const NetworkInspector = ({ enabled = true, storage, }) => {
|
|
|
4264
4402
|
</react_native_1.View>
|
|
4265
4403
|
|
|
4266
4404
|
<react_native_1.View style={styles_1.default.toolbarRight}>
|
|
4267
|
-
<TouchableScale_1.default style={
|
|
4268
|
-
|
|
4269
|
-
|
|
4270
|
-
|
|
4271
|
-
|
|
4272
|
-
|
|
4273
|
-
|
|
4405
|
+
<TouchableScale_1.default style={{
|
|
4406
|
+
flexDirection: 'row',
|
|
4407
|
+
alignItems: 'center',
|
|
4408
|
+
gap: 4,
|
|
4409
|
+
paddingHorizontal: 10,
|
|
4410
|
+
paddingVertical: 5,
|
|
4411
|
+
borderRadius: 8,
|
|
4412
|
+
backgroundColor: 'rgba(255,46,87,0.06)',
|
|
4413
|
+
borderWidth: 1,
|
|
4414
|
+
borderColor: 'rgba(255,46,87,0.15)',
|
|
4415
|
+
}} onPress={handleDelete} hitSlop={6}>
|
|
4416
|
+
<NetworkIcons_1.WipeIcon color={AppColors_1.AppColors.errorColor} size={13}/>
|
|
4417
|
+
<react_native_1.Text style={{
|
|
4418
|
+
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
4419
|
+
fontSize: 10.5,
|
|
4420
|
+
color: AppColors_1.AppColors.errorColor,
|
|
4421
|
+
}}>
|
|
4422
|
+
{selectedLogs.size > 0
|
|
4423
|
+
? `Delete (${selectedLogs.size})`
|
|
4424
|
+
: 'Clear'}
|
|
4425
|
+
</react_native_1.Text>
|
|
4274
4426
|
</TouchableScale_1.default>
|
|
4275
4427
|
|
|
4276
4428
|
<TouchableScale_1.default style={styles_1.default.toolbarBtn} onPress={() => setSortOrder(o => o === 'newest' ? 'oldest' : 'newest')} hitSlop={10}>
|
|
@@ -4438,8 +4590,25 @@ const NetworkInspector = ({ enabled = true, storage, }) => {
|
|
|
4438
4590
|
<TouchableScale_1.default style={styles_1.default.toolbarBtn} onPress={() => setLogSortOrder(o => o === 'newest' ? 'oldest' : 'newest')} hitSlop={10}>
|
|
4439
4591
|
<NetworkIcons_1.SortArrowIcon color={AppColors_1.AppColors.grayTextStrong} size={18} direction={logSortOrder === 'newest' ? 'down' : 'up'}/>
|
|
4440
4592
|
</TouchableScale_1.default>
|
|
4441
|
-
<TouchableScale_1.default style={
|
|
4442
|
-
|
|
4593
|
+
<TouchableScale_1.default style={{
|
|
4594
|
+
flexDirection: 'row',
|
|
4595
|
+
alignItems: 'center',
|
|
4596
|
+
gap: 4,
|
|
4597
|
+
paddingHorizontal: 10,
|
|
4598
|
+
paddingVertical: 5,
|
|
4599
|
+
borderRadius: 8,
|
|
4600
|
+
backgroundColor: 'rgba(255,46,87,0.06)',
|
|
4601
|
+
borderWidth: 1,
|
|
4602
|
+
borderColor: 'rgba(255,46,87,0.15)',
|
|
4603
|
+
}} onPress={handleDelete} hitSlop={6}>
|
|
4604
|
+
<NetworkIcons_1.WipeIcon color={AppColors_1.AppColors.errorColor} size={13}/>
|
|
4605
|
+
<react_native_1.Text style={{
|
|
4606
|
+
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
4607
|
+
fontSize: 10.5,
|
|
4608
|
+
color: AppColors_1.AppColors.errorColor,
|
|
4609
|
+
}}>
|
|
4610
|
+
Clear
|
|
4611
|
+
</react_native_1.Text>
|
|
4443
4612
|
</TouchableScale_1.default>
|
|
4444
4613
|
</react_native_1.View>
|
|
4445
4614
|
</react_native_1.View>
|
|
@@ -724,6 +724,9 @@ export declare const getRawStyles: (colors: typeof AppColors) => {
|
|
|
724
724
|
paddingVertical: number;
|
|
725
725
|
borderRadius: number;
|
|
726
726
|
marginRight: number;
|
|
727
|
+
minWidth: number;
|
|
728
|
+
alignItems: string;
|
|
729
|
+
justifyContent: string;
|
|
727
730
|
shadowColor: string;
|
|
728
731
|
shadowOffset: {
|
|
729
732
|
width: number;
|
|
@@ -689,10 +689,13 @@ const getRawStyles = (colors) => ({
|
|
|
689
689
|
fontSize: 10,
|
|
690
690
|
},
|
|
691
691
|
methodBadge: {
|
|
692
|
-
paddingHorizontal:
|
|
693
|
-
paddingVertical:
|
|
694
|
-
borderRadius:
|
|
695
|
-
marginRight:
|
|
692
|
+
paddingHorizontal: 6,
|
|
693
|
+
paddingVertical: 3,
|
|
694
|
+
borderRadius: 6,
|
|
695
|
+
marginRight: 6,
|
|
696
|
+
minWidth: 46,
|
|
697
|
+
alignItems: 'center',
|
|
698
|
+
justifyContent: 'center',
|
|
696
699
|
shadowColor: '#000000',
|
|
697
700
|
shadowOffset: { width: 0, height: 1 },
|
|
698
701
|
shadowOpacity: 0.08,
|
|
@@ -701,8 +704,8 @@ const getRawStyles = (colors) => ({
|
|
|
701
704
|
},
|
|
702
705
|
methodBadgeText: {
|
|
703
706
|
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
704
|
-
fontSize:
|
|
705
|
-
letterSpacing: 0.
|
|
707
|
+
fontSize: 9.5,
|
|
708
|
+
letterSpacing: 0.4,
|
|
706
709
|
},
|
|
707
710
|
timelineTrack: {
|
|
708
711
|
height: 3,
|
|
@@ -3,8 +3,9 @@ import { Animated, View, Pressable, Text, StyleSheet } from 'react-native';
|
|
|
3
3
|
import Svg, { Path } from 'react-native-svg';
|
|
4
4
|
import { AppColors } from '../styles/AppColors';
|
|
5
5
|
import { METHOD_COLORS } from '../constants';
|
|
6
|
-
import { getStatusColor, getDurationColor, getPath, formatDateTime, } from '../helpers';
|
|
6
|
+
import { getStatusColor, getDurationColor, getPath, getBaseUrl, formatDateTime, } from '../helpers';
|
|
7
7
|
import { CalendarIcon, ClockIcon } from './NetworkIcons';
|
|
8
|
+
import { AppFonts } from '../styles/AppFonts';
|
|
8
9
|
import styles from '../styles';
|
|
9
10
|
import HighlightText from './HighlightText';
|
|
10
11
|
import TouchableScale from './TouchableScale';
|
|
@@ -36,6 +37,8 @@ const LogCard = React.memo(function LogCard({ item, onPress, timelineMinStart, t
|
|
|
36
37
|
}
|
|
37
38
|
}, [isNew]);
|
|
38
39
|
const path = getPath(item.url);
|
|
40
|
+
const baseUrl = getBaseUrl(item.url) || item.url;
|
|
41
|
+
const showPathRow = baseUrl !== item.url && path !== '/';
|
|
39
42
|
const triggeredAt = formatDateTime(item.startTime);
|
|
40
43
|
const isJson = item.url.split('?')[0].toLowerCase().endsWith('.json');
|
|
41
44
|
return (<TouchableScale onPress={onPress} style={[
|
|
@@ -64,7 +67,7 @@ const LogCard = React.memo(function LogCard({ item, onPress, timelineMinStart, t
|
|
|
64
67
|
</Text>
|
|
65
68
|
</View>
|
|
66
69
|
|
|
67
|
-
<HighlightText text={
|
|
70
|
+
<HighlightText text={baseUrl} search={searchStr} style={styles.urlPathText} highlightStyle={styles.highlight} numberOfLines={0}/>
|
|
68
71
|
|
|
69
72
|
{isJson && (<View style={[
|
|
70
73
|
styles.chip,
|
|
@@ -97,6 +100,16 @@ const LogCard = React.memo(function LogCard({ item, onPress, timelineMinStart, t
|
|
|
97
100
|
</View>)}
|
|
98
101
|
</View>
|
|
99
102
|
|
|
103
|
+
{showPathRow && (<View style={{ flexDirection: 'row', alignItems: 'flex-start', marginTop: 3, marginBottom: 5, paddingLeft: 30, gap: 6 }}>
|
|
104
|
+
<Text style={{ color: AppColors.grayTextWeak, fontSize: 9, fontFamily: AppFonts.interBold, letterSpacing: 0.5, marginTop: 2.5 }}>PATH</Text>
|
|
105
|
+
<HighlightText text={path} search={searchStr} style={{
|
|
106
|
+
fontFamily: AppFonts.Sfprotext || 'System',
|
|
107
|
+
fontSize: 12,
|
|
108
|
+
color: AppColors.grayText,
|
|
109
|
+
flex: 1,
|
|
110
|
+
}} highlightStyle={styles.highlight} numberOfLines={0}/>
|
|
111
|
+
</View>)}
|
|
112
|
+
|
|
100
113
|
<View style={styles.cardBottomRow}>
|
|
101
114
|
<View style={styles.cardDateRow}>
|
|
102
115
|
<CalendarIcon color={AppColors.grayTextWeak} size={11}/>
|
|
@@ -49,3 +49,4 @@ export declare const InfoCircleIcon: ({ color, size, }: any) => React.JSX.Elemen
|
|
|
49
49
|
export declare const WarningTriangleIcon: ({ color, size, }: any) => React.JSX.Element;
|
|
50
50
|
export declare const ErrorCircleIcon: ({ color, size, }: any) => React.JSX.Element;
|
|
51
51
|
export declare const TrendingUpIcon: ({ color, size, }: any) => React.JSX.Element;
|
|
52
|
+
export declare const MotionIcon: ({ color, size, }: any) => React.JSX.Element;
|
|
@@ -297,3 +297,8 @@ export const TrendingUpIcon = ({ color = AppColors.grayTextWeak, size = 12, }) =
|
|
|
297
297
|
<Path d="M17 6h6v6" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
|
|
298
298
|
</Svg>);
|
|
299
299
|
};
|
|
300
|
+
export const MotionIcon = ({ color = AppColors.grayTextWeak, size = 14, }) => {
|
|
301
|
+
return (<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
302
|
+
<Path d="M5 3l14 9-14 9V3z" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
|
|
303
|
+
</Svg>);
|
|
304
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const LIB_VERSION = "1.1.
|
|
1
|
+
export declare const LIB_VERSION = "1.1.9";
|
|
@@ -6,6 +6,7 @@ export declare const getDurationColor: (duration: number | null) => string;
|
|
|
6
6
|
export declare const getSize: (data: unknown) => string;
|
|
7
7
|
export declare const copyToClipboard: (value: unknown, label: string) => void;
|
|
8
8
|
export declare const getPath: (url: string) => string;
|
|
9
|
+
export declare const getBaseUrl: (url: string) => string;
|
|
9
10
|
export declare const getCurlCommand: (log: NetworkLog) => string;
|
|
10
11
|
export declare const getFetchCommand: (log: NetworkLog) => string;
|
|
11
12
|
export declare const deduplicateLogs: (raw: NetworkLog[]) => NetworkLog[];
|
|
@@ -73,6 +73,16 @@ export const getPath = (url) => {
|
|
|
73
73
|
return withoutDomain || '/';
|
|
74
74
|
}
|
|
75
75
|
};
|
|
76
|
+
export const getBaseUrl = (url) => {
|
|
77
|
+
try {
|
|
78
|
+
const u = new URL(url);
|
|
79
|
+
return `${u.protocol}//${u.host}`;
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
const match = url.match(/^(https?:\/\/[^/]+)/);
|
|
83
|
+
return match ? match[1] : '';
|
|
84
|
+
}
|
|
85
|
+
};
|
|
76
86
|
export const getCurlCommand = (log) => {
|
|
77
87
|
let cmd = `curl -X ${log.method} "${log.url}"`;
|
|
78
88
|
if (log.requestHeaders) {
|
|
@@ -6,6 +6,7 @@ export declare function setCustomStorage(storage: InspectorStorage | null): void
|
|
|
6
6
|
export interface PersistedSettings {
|
|
7
7
|
isDark?: boolean;
|
|
8
8
|
modalHeightPercent?: number;
|
|
9
|
+
modalAnimationType?: string;
|
|
9
10
|
tabVisibility?: Record<string, boolean>;
|
|
10
11
|
defaultTab?: string;
|
|
11
12
|
maxNetworkLogs?: number;
|
package/dist/esm/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useEffect, useMemo, useRef, useState, useCallback } from 'react';
|
|
2
|
-
import { Alert, Animated, StyleSheet, FlatList, LayoutAnimation, Modal, PanResponder, Platform, Pressable, ScrollView, Text, TextInput, View, Linking, Image, InteractionManager, ActivityIndicator, StatusBar, TouchableOpacity, UIManager, LogBox,
|
|
2
|
+
import { Alert, Animated, StyleSheet, FlatList, LayoutAnimation, Modal, PanResponder, Platform, Pressable, ScrollView, Text, TextInput, View, Linking, Image, InteractionManager, ActivityIndicator, StatusBar, TouchableOpacity, UIManager, LogBox, } from 'react-native';
|
|
3
3
|
import Svg, { Circle, Path } from 'react-native-svg';
|
|
4
4
|
import LinearGradient from 'react-native-linear-gradient';
|
|
5
5
|
import { useNavigationState, NavigationContext } from '@react-navigation/native';
|
|
@@ -26,7 +26,7 @@ import { formatDateTime, getStatusColor, getNavigationInfo, deduplicateLogs, get
|
|
|
26
26
|
// #5 — settings persistence
|
|
27
27
|
import { loadSettings, saveSettings, setCustomStorage, isPersistentStorageAvailable, clearPersistedSettings, } from './helpers/settingsStore';
|
|
28
28
|
// Assets
|
|
29
|
-
import { EmptyRadarIcon, FailIcon, SearchIcon, ScreenIcon, ClearIcon, SortArrowIcon, FilterIcon, InsightsIcon, GlobeIcon, DownloadIcon, CloseWhite, TrashIcon, WhiteBackNavigation, TerminalIcon, SignalIcon, AnalyticsIcon, SunIcon, MoonIcon, BrandCircleIcon, BrandSquareIcon, HtmlIcon, CssIcon, JsIcon, ClockIcon, EyeIcon, CheckIcon, SettingsIcon, RequestIcon, ResponseIcon, HeadersIcon, StatusIcon, ChevronIcon, WipeIcon, LayersIcon, UserIcon, InfoCircleIcon, WarningTriangleIcon, ErrorCircleIcon, TrendingUpIcon, } from './components/NetworkIcons';
|
|
29
|
+
import { EmptyRadarIcon, FailIcon, SearchIcon, ScreenIcon, ClearIcon, SortArrowIcon, FilterIcon, InsightsIcon, GlobeIcon, DownloadIcon, CloseWhite, TrashIcon, WhiteBackNavigation, TerminalIcon, SignalIcon, AnalyticsIcon, SunIcon, MoonIcon, BrandCircleIcon, BrandSquareIcon, HtmlIcon, CssIcon, JsIcon, ClockIcon, EyeIcon, CheckIcon, SettingsIcon, RequestIcon, ResponseIcon, HeadersIcon, StatusIcon, ChevronIcon, WipeIcon, LayersIcon, UserIcon, InfoCircleIcon, WarningTriangleIcon, ErrorCircleIcon, TrendingUpIcon, MotionIcon, } from './components/NetworkIcons';
|
|
30
30
|
import ErrorBoundary from './components/ErrorBoundary';
|
|
31
31
|
// Stylesheet
|
|
32
32
|
import { AppColors } from './styles/AppColors';
|
|
@@ -113,7 +113,7 @@ const NavigationTracker = ({ onStateChange }) => {
|
|
|
113
113
|
const animateNextLayout = () => {
|
|
114
114
|
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
|
|
115
115
|
};
|
|
116
|
-
const NetworkInspector = ({ enabled = true, storage, }) => {
|
|
116
|
+
const NetworkInspector = ({ enabled = true, storage, navigationRef, }) => {
|
|
117
117
|
// Set custom storage synchronously during render phase
|
|
118
118
|
setCustomStorage(storage || null);
|
|
119
119
|
const [isDark, setIsDark] = useState(false);
|
|
@@ -124,6 +124,8 @@ const NetworkInspector = ({ enabled = true, storage, }) => {
|
|
|
124
124
|
const [reduxLastActionMap, setReduxLastActionMap] = useState({});
|
|
125
125
|
// Inspector panel height as a percentage of the screen (configurable in Settings).
|
|
126
126
|
const [modalHeightPercent, setModalHeightPercent] = useState(90);
|
|
127
|
+
const [modalAnimationType, setModalAnimationType] = useState('slide');
|
|
128
|
+
const headerTopPadding = Platform.OS === 'ios' && modalHeightPercent >= 95 ? 44 : 0;
|
|
127
129
|
const [expandedReducers, setExpandedReducers] = useState({});
|
|
128
130
|
const [logs, setLogs] = useState([]);
|
|
129
131
|
const [visible, setVisible] = useState(false);
|
|
@@ -251,6 +253,7 @@ const NetworkInspector = ({ enabled = true, storage, }) => {
|
|
|
251
253
|
setIsDark(false);
|
|
252
254
|
toggleGlobalTheme(false);
|
|
253
255
|
setModalHeightPercent(90);
|
|
256
|
+
setModalAnimationType('slide');
|
|
254
257
|
setTabVisibility({
|
|
255
258
|
insights: true,
|
|
256
259
|
apis: true,
|
|
@@ -288,6 +291,8 @@ const NetworkInspector = ({ enabled = true, storage, }) => {
|
|
|
288
291
|
}
|
|
289
292
|
if (saved.modalHeightPercent != null)
|
|
290
293
|
setModalHeightPercent(saved.modalHeightPercent);
|
|
294
|
+
if (saved.modalAnimationType)
|
|
295
|
+
setModalAnimationType(saved.modalAnimationType);
|
|
291
296
|
if (saved.tabVisibility)
|
|
292
297
|
setTabVisibility(prev => ({
|
|
293
298
|
...prev,
|
|
@@ -342,6 +347,7 @@ const NetworkInspector = ({ enabled = true, storage, }) => {
|
|
|
342
347
|
saveSettings({
|
|
343
348
|
isDark,
|
|
344
349
|
modalHeightPercent,
|
|
350
|
+
modalAnimationType,
|
|
345
351
|
tabVisibility,
|
|
346
352
|
defaultTab,
|
|
347
353
|
maxNetworkLogs,
|
|
@@ -357,6 +363,7 @@ const NetworkInspector = ({ enabled = true, storage, }) => {
|
|
|
357
363
|
}, [
|
|
358
364
|
isDark,
|
|
359
365
|
modalHeightPercent,
|
|
366
|
+
modalAnimationType,
|
|
360
367
|
tabVisibility,
|
|
361
368
|
defaultTab,
|
|
362
369
|
maxNetworkLogs,
|
|
@@ -499,6 +506,36 @@ const NetworkInspector = ({ enabled = true, storage, }) => {
|
|
|
499
506
|
currentRouteRef.current = getNavigationInfo(navState);
|
|
500
507
|
}
|
|
501
508
|
}, [navState]);
|
|
509
|
+
useEffect(() => {
|
|
510
|
+
if (!navigationRef)
|
|
511
|
+
return;
|
|
512
|
+
const updateState = () => {
|
|
513
|
+
try {
|
|
514
|
+
if (typeof navigationRef.isReady === 'function' && navigationRef.isReady()) {
|
|
515
|
+
const state = navigationRef.getRootState();
|
|
516
|
+
if (state) {
|
|
517
|
+
setNavState(state);
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
catch (err) {
|
|
522
|
+
// Safe check
|
|
523
|
+
}
|
|
524
|
+
};
|
|
525
|
+
// Initialize state
|
|
526
|
+
updateState();
|
|
527
|
+
// Listen to changes
|
|
528
|
+
const unsubscribe = typeof navigationRef.addListener === 'function'
|
|
529
|
+
? navigationRef.addListener('state', () => {
|
|
530
|
+
updateState();
|
|
531
|
+
})
|
|
532
|
+
: null;
|
|
533
|
+
return () => {
|
|
534
|
+
if (unsubscribe) {
|
|
535
|
+
unsubscribe();
|
|
536
|
+
}
|
|
537
|
+
};
|
|
538
|
+
}, [navigationRef]);
|
|
502
539
|
const logRouteMapRef = useRef(new Map());
|
|
503
540
|
const prevLogIdsRef = useRef(new Set());
|
|
504
541
|
const [newLogIds, setNewLogIds] = useState(new Set());
|
|
@@ -1323,7 +1360,7 @@ const NetworkInspector = ({ enabled = true, storage, }) => {
|
|
|
1323
1360
|
return (<View style={{ flex: 1, backgroundColor: AppColors.grayBackground }}>
|
|
1324
1361
|
{/* Settings Header with back button */}
|
|
1325
1362
|
<LinearGradient colors={[AppColors.purple, '#6B4EFF']} start={{ x: 0, y: 0 }} end={{ x: 1, y: 0 }} style={styles.headerGradient}>
|
|
1326
|
-
<
|
|
1363
|
+
<View style={{ paddingTop: headerTopPadding, width: '100%' }}>
|
|
1327
1364
|
<View style={[styles.header, { paddingHorizontal: 16, gap: 12 }]}>
|
|
1328
1365
|
<TouchableScale onPress={() => {
|
|
1329
1366
|
animateNextLayout();
|
|
@@ -1372,7 +1409,7 @@ const NetworkInspector = ({ enabled = true, storage, }) => {
|
|
|
1372
1409
|
</Text>
|
|
1373
1410
|
</View>
|
|
1374
1411
|
</View>
|
|
1375
|
-
</
|
|
1412
|
+
</View>
|
|
1376
1413
|
</LinearGradient>
|
|
1377
1414
|
|
|
1378
1415
|
<ScrollView style={{ flex: 1 }} contentContainerStyle={{ padding: 16, gap: 12 }}>
|
|
@@ -1799,6 +1836,90 @@ const NetworkInspector = ({ enabled = true, storage, }) => {
|
|
|
1799
1836
|
</View>
|
|
1800
1837
|
</View>
|
|
1801
1838
|
|
|
1839
|
+
{/* Divider */}
|
|
1840
|
+
<View style={{
|
|
1841
|
+
height: 1,
|
|
1842
|
+
backgroundColor: AppColors.dividerColor,
|
|
1843
|
+
}}/>
|
|
1844
|
+
|
|
1845
|
+
{/* Modal Animation */}
|
|
1846
|
+
<View style={{
|
|
1847
|
+
paddingVertical: 12,
|
|
1848
|
+
paddingHorizontal: 14,
|
|
1849
|
+
}}>
|
|
1850
|
+
<View style={{
|
|
1851
|
+
flexDirection: 'row',
|
|
1852
|
+
alignItems: 'center',
|
|
1853
|
+
gap: 8,
|
|
1854
|
+
}}>
|
|
1855
|
+
<View style={{
|
|
1856
|
+
width: 20,
|
|
1857
|
+
height: 20,
|
|
1858
|
+
borderRadius: 6,
|
|
1859
|
+
backgroundColor: AppColors.purpleShade50,
|
|
1860
|
+
borderWidth: 1,
|
|
1861
|
+
borderColor: 'rgba(104,75,155,0.2)',
|
|
1862
|
+
alignItems: 'center',
|
|
1863
|
+
justifyContent: 'center',
|
|
1864
|
+
}}>
|
|
1865
|
+
<MotionIcon color={AppColors.purple} size={11}/>
|
|
1866
|
+
</View>
|
|
1867
|
+
<View style={{ flex: 1 }}>
|
|
1868
|
+
<Text style={{
|
|
1869
|
+
fontFamily: AppFonts.interBold,
|
|
1870
|
+
fontSize: 13,
|
|
1871
|
+
color: AppColors.primaryBlack,
|
|
1872
|
+
}}>
|
|
1873
|
+
Modal Animation
|
|
1874
|
+
</Text>
|
|
1875
|
+
<Text style={{
|
|
1876
|
+
fontFamily: AppFonts.interRegular,
|
|
1877
|
+
fontSize: 11,
|
|
1878
|
+
color: AppColors.grayText,
|
|
1879
|
+
marginTop: 1,
|
|
1880
|
+
}}>
|
|
1881
|
+
How the inspector panel enters and exits the screen
|
|
1882
|
+
</Text>
|
|
1883
|
+
</View>
|
|
1884
|
+
</View>
|
|
1885
|
+
|
|
1886
|
+
{/* Segmented picker */}
|
|
1887
|
+
<View style={{
|
|
1888
|
+
flexDirection: 'row',
|
|
1889
|
+
backgroundColor: AppColors.grayBackground,
|
|
1890
|
+
borderRadius: 8,
|
|
1891
|
+
padding: 2.5,
|
|
1892
|
+
marginTop: 10,
|
|
1893
|
+
borderWidth: 1,
|
|
1894
|
+
borderColor: AppColors.dividerColor,
|
|
1895
|
+
}}>
|
|
1896
|
+
{([
|
|
1897
|
+
{ key: 'slide', label: 'Slide Up' },
|
|
1898
|
+
{ key: 'fade', label: 'Fade' },
|
|
1899
|
+
{ key: 'none', label: 'None' },
|
|
1900
|
+
]).map(opt => {
|
|
1901
|
+
const isActive = modalAnimationType === opt.key;
|
|
1902
|
+
return (<TouchableScale key={opt.key} onPress={() => setModalAnimationType(opt.key)} style={{
|
|
1903
|
+
flex: 1,
|
|
1904
|
+
paddingVertical: 6,
|
|
1905
|
+
alignItems: 'center',
|
|
1906
|
+
borderRadius: 6,
|
|
1907
|
+
backgroundColor: isActive
|
|
1908
|
+
? AppColors.purple
|
|
1909
|
+
: 'transparent',
|
|
1910
|
+
}}>
|
|
1911
|
+
<Text style={{
|
|
1912
|
+
fontFamily: AppFonts.interBold,
|
|
1913
|
+
fontSize: 11,
|
|
1914
|
+
color: isActive ? '#FFFFFF' : AppColors.grayText,
|
|
1915
|
+
}}>
|
|
1916
|
+
{opt.label}
|
|
1917
|
+
</Text>
|
|
1918
|
+
</TouchableScale>);
|
|
1919
|
+
})}
|
|
1920
|
+
</View>
|
|
1921
|
+
</View>
|
|
1922
|
+
|
|
1802
1923
|
{/* Divider */}
|
|
1803
1924
|
<View style={{
|
|
1804
1925
|
height: 1,
|
|
@@ -2640,7 +2761,7 @@ const NetworkInspector = ({ enabled = true, storage, }) => {
|
|
|
2640
2761
|
}
|
|
2641
2762
|
return (<View style={{ flex: 1, backgroundColor: AppColors.grayBackground }}>
|
|
2642
2763
|
<LinearGradient colors={[AppColors.purple, '#6B4EFF']} start={{ x: 0, y: 0 }} end={{ x: 1, y: 0 }} style={styles.headerGradient}>
|
|
2643
|
-
<
|
|
2764
|
+
<View style={{ paddingTop: headerTopPadding, width: '100%' }}>
|
|
2644
2765
|
<View style={[styles.header, { paddingHorizontal: 16, gap: 12 }]}>
|
|
2645
2766
|
<TouchableScale onPress={goBackToMain} hitSlop={12} style={{
|
|
2646
2767
|
padding: 8,
|
|
@@ -2687,7 +2808,7 @@ const NetworkInspector = ({ enabled = true, storage, }) => {
|
|
|
2687
2808
|
</Text>
|
|
2688
2809
|
</View>) : null}
|
|
2689
2810
|
</View>
|
|
2690
|
-
</
|
|
2811
|
+
</View>
|
|
2691
2812
|
</LinearGradient>
|
|
2692
2813
|
{content}
|
|
2693
2814
|
</View>);
|
|
@@ -3524,7 +3645,7 @@ const NetworkInspector = ({ enabled = true, storage, }) => {
|
|
|
3524
3645
|
</TouchableScale>
|
|
3525
3646
|
</Animated.View>
|
|
3526
3647
|
|
|
3527
|
-
<Modal visible={visible} animationType=
|
|
3648
|
+
<Modal visible={visible} animationType={modalAnimationType} transparent>
|
|
3528
3649
|
{visible && (<ErrorBoundary onClose={closeModal}>
|
|
3529
3650
|
<View style={styles.modalBackdrop}>
|
|
3530
3651
|
<Pressable style={styles.modalBackdropPressable} onPress={closeModal}/>
|
|
@@ -3535,7 +3656,7 @@ const NetworkInspector = ({ enabled = true, storage, }) => {
|
|
|
3535
3656
|
<StatusBar translucent backgroundColor="transparent" barStyle="light-content"/>
|
|
3536
3657
|
|
|
3537
3658
|
<LinearGradient colors={[AppColors.purple, '#6B4EFF']} style={styles.headerGradient}>
|
|
3538
|
-
<
|
|
3659
|
+
<View style={{ paddingTop: headerTopPadding, width: '100%' }}>
|
|
3539
3660
|
<View style={styles.header}>
|
|
3540
3661
|
<View style={[
|
|
3541
3662
|
styles.headerLeft,
|
|
@@ -3873,7 +3994,7 @@ const NetworkInspector = ({ enabled = true, storage, }) => {
|
|
|
3873
3994
|
</TouchableScale>
|
|
3874
3995
|
</View>
|
|
3875
3996
|
</View>
|
|
3876
|
-
</
|
|
3997
|
+
</View>
|
|
3877
3998
|
</LinearGradient>
|
|
3878
3999
|
|
|
3879
4000
|
{/* ─── Horizontal Scrollable Tab Bar inside Content ─── */}
|
|
@@ -3998,8 +4119,25 @@ const NetworkInspector = ({ enabled = true, storage, }) => {
|
|
|
3998
4119
|
? AppColors.purple
|
|
3999
4120
|
: AppColors.grayTextStrong} size={18}/>
|
|
4000
4121
|
</TouchableScale>
|
|
4001
|
-
<TouchableScale style={
|
|
4002
|
-
|
|
4122
|
+
<TouchableScale style={{
|
|
4123
|
+
flexDirection: 'row',
|
|
4124
|
+
alignItems: 'center',
|
|
4125
|
+
gap: 4,
|
|
4126
|
+
paddingHorizontal: 10,
|
|
4127
|
+
paddingVertical: 5,
|
|
4128
|
+
borderRadius: 8,
|
|
4129
|
+
backgroundColor: 'rgba(255,46,87,0.06)',
|
|
4130
|
+
borderWidth: 1,
|
|
4131
|
+
borderColor: 'rgba(255,46,87,0.15)',
|
|
4132
|
+
}} onPress={handleDelete} hitSlop={6}>
|
|
4133
|
+
<WipeIcon color={AppColors.errorColor} size={13}/>
|
|
4134
|
+
<Text style={{
|
|
4135
|
+
fontFamily: AppFonts.interBold,
|
|
4136
|
+
fontSize: 10.5,
|
|
4137
|
+
color: AppColors.errorColor,
|
|
4138
|
+
}}>
|
|
4139
|
+
Clear
|
|
4140
|
+
</Text>
|
|
4003
4141
|
</TouchableScale>
|
|
4004
4142
|
</View>)}
|
|
4005
4143
|
</View>
|
|
@@ -4225,13 +4363,27 @@ const NetworkInspector = ({ enabled = true, storage, }) => {
|
|
|
4225
4363
|
</View>
|
|
4226
4364
|
|
|
4227
4365
|
<View style={styles.toolbarRight}>
|
|
4228
|
-
<TouchableScale style={
|
|
4229
|
-
|
|
4230
|
-
|
|
4231
|
-
|
|
4232
|
-
|
|
4233
|
-
|
|
4234
|
-
|
|
4366
|
+
<TouchableScale style={{
|
|
4367
|
+
flexDirection: 'row',
|
|
4368
|
+
alignItems: 'center',
|
|
4369
|
+
gap: 4,
|
|
4370
|
+
paddingHorizontal: 10,
|
|
4371
|
+
paddingVertical: 5,
|
|
4372
|
+
borderRadius: 8,
|
|
4373
|
+
backgroundColor: 'rgba(255,46,87,0.06)',
|
|
4374
|
+
borderWidth: 1,
|
|
4375
|
+
borderColor: 'rgba(255,46,87,0.15)',
|
|
4376
|
+
}} onPress={handleDelete} hitSlop={6}>
|
|
4377
|
+
<WipeIcon color={AppColors.errorColor} size={13}/>
|
|
4378
|
+
<Text style={{
|
|
4379
|
+
fontFamily: AppFonts.interBold,
|
|
4380
|
+
fontSize: 10.5,
|
|
4381
|
+
color: AppColors.errorColor,
|
|
4382
|
+
}}>
|
|
4383
|
+
{selectedLogs.size > 0
|
|
4384
|
+
? `Delete (${selectedLogs.size})`
|
|
4385
|
+
: 'Clear'}
|
|
4386
|
+
</Text>
|
|
4235
4387
|
</TouchableScale>
|
|
4236
4388
|
|
|
4237
4389
|
<TouchableScale style={styles.toolbarBtn} onPress={() => setSortOrder(o => o === 'newest' ? 'oldest' : 'newest')} hitSlop={10}>
|
|
@@ -4399,8 +4551,25 @@ const NetworkInspector = ({ enabled = true, storage, }) => {
|
|
|
4399
4551
|
<TouchableScale style={styles.toolbarBtn} onPress={() => setLogSortOrder(o => o === 'newest' ? 'oldest' : 'newest')} hitSlop={10}>
|
|
4400
4552
|
<SortArrowIcon color={AppColors.grayTextStrong} size={18} direction={logSortOrder === 'newest' ? 'down' : 'up'}/>
|
|
4401
4553
|
</TouchableScale>
|
|
4402
|
-
<TouchableScale style={
|
|
4403
|
-
|
|
4554
|
+
<TouchableScale style={{
|
|
4555
|
+
flexDirection: 'row',
|
|
4556
|
+
alignItems: 'center',
|
|
4557
|
+
gap: 4,
|
|
4558
|
+
paddingHorizontal: 10,
|
|
4559
|
+
paddingVertical: 5,
|
|
4560
|
+
borderRadius: 8,
|
|
4561
|
+
backgroundColor: 'rgba(255,46,87,0.06)',
|
|
4562
|
+
borderWidth: 1,
|
|
4563
|
+
borderColor: 'rgba(255,46,87,0.15)',
|
|
4564
|
+
}} onPress={handleDelete} hitSlop={6}>
|
|
4565
|
+
<WipeIcon color={AppColors.errorColor} size={13}/>
|
|
4566
|
+
<Text style={{
|
|
4567
|
+
fontFamily: AppFonts.interBold,
|
|
4568
|
+
fontSize: 10.5,
|
|
4569
|
+
color: AppColors.errorColor,
|
|
4570
|
+
}}>
|
|
4571
|
+
Clear
|
|
4572
|
+
</Text>
|
|
4404
4573
|
</TouchableScale>
|
|
4405
4574
|
</View>
|
|
4406
4575
|
</View>
|
|
@@ -724,6 +724,9 @@ export declare const getRawStyles: (colors: typeof AppColors) => {
|
|
|
724
724
|
paddingVertical: number;
|
|
725
725
|
borderRadius: number;
|
|
726
726
|
marginRight: number;
|
|
727
|
+
minWidth: number;
|
|
728
|
+
alignItems: string;
|
|
729
|
+
justifyContent: string;
|
|
727
730
|
shadowColor: string;
|
|
728
731
|
shadowOffset: {
|
|
729
732
|
width: number;
|
package/dist/esm/styles/index.js
CHANGED
|
@@ -653,10 +653,13 @@ export const getRawStyles = (colors) => ({
|
|
|
653
653
|
fontSize: 10,
|
|
654
654
|
},
|
|
655
655
|
methodBadge: {
|
|
656
|
-
paddingHorizontal:
|
|
657
|
-
paddingVertical:
|
|
658
|
-
borderRadius:
|
|
659
|
-
marginRight:
|
|
656
|
+
paddingHorizontal: 6,
|
|
657
|
+
paddingVertical: 3,
|
|
658
|
+
borderRadius: 6,
|
|
659
|
+
marginRight: 6,
|
|
660
|
+
minWidth: 46,
|
|
661
|
+
alignItems: 'center',
|
|
662
|
+
justifyContent: 'center',
|
|
660
663
|
shadowColor: '#000000',
|
|
661
664
|
shadowOffset: { width: 0, height: 1 },
|
|
662
665
|
shadowOpacity: 0.08,
|
|
@@ -665,8 +668,8 @@ export const getRawStyles = (colors) => ({
|
|
|
665
668
|
},
|
|
666
669
|
methodBadgeText: {
|
|
667
670
|
fontFamily: AppFonts.interBold,
|
|
668
|
-
fontSize:
|
|
669
|
-
letterSpacing: 0.
|
|
671
|
+
fontSize: 9.5,
|
|
672
|
+
letterSpacing: 0.4,
|
|
670
673
|
},
|
|
671
674
|
timelineTrack: {
|
|
672
675
|
height: 3,
|
package/example/App.tsx
CHANGED
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
useColorScheme,
|
|
10
10
|
} from 'react-native';
|
|
11
11
|
import { SafeAreaProvider, SafeAreaView } from 'react-native-safe-area-context';
|
|
12
|
-
import { NavigationContainer } from '@react-navigation/native';
|
|
12
|
+
import { NavigationContainer, createNavigationContainerRef } from '@react-navigation/native';
|
|
13
13
|
import { createNativeStackNavigator } from '@react-navigation/native-stack';
|
|
14
14
|
import axios from 'axios';
|
|
15
15
|
import NetworkInspector, {
|
|
@@ -574,6 +574,7 @@ function WebViewScreen({ navigation }: any) {
|
|
|
574
574
|
}
|
|
575
575
|
|
|
576
576
|
const Stack = createNativeStackNavigator();
|
|
577
|
+
const navigationRef = createNavigationContainerRef();
|
|
577
578
|
|
|
578
579
|
function App() {
|
|
579
580
|
const isDarkMode = useColorScheme() === 'dark';
|
|
@@ -582,7 +583,7 @@ function App() {
|
|
|
582
583
|
<SafeAreaProvider>
|
|
583
584
|
<StatusBar barStyle={isDarkMode ? 'light-content' : 'dark-content'} />
|
|
584
585
|
<ErrorBoundary>
|
|
585
|
-
<NavigationContainer>
|
|
586
|
+
<NavigationContainer ref={navigationRef}>
|
|
586
587
|
<Stack.Navigator
|
|
587
588
|
screenOptions={{
|
|
588
589
|
headerShown: false,
|
|
@@ -597,7 +598,7 @@ function App() {
|
|
|
597
598
|
</Stack.Navigator>
|
|
598
599
|
</NavigationContainer>
|
|
599
600
|
{/* Render inspector globally exactly once at the root level */}
|
|
600
|
-
<NetworkInspector />
|
|
601
|
+
<NetworkInspector navigationRef={navigationRef} />
|
|
601
602
|
</ErrorBoundary>
|
|
602
603
|
</SafeAreaProvider>
|
|
603
604
|
);
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"eslint": "^8.19.0",
|
|
39
39
|
"jest": "^29.6.3",
|
|
40
40
|
"prettier": "2.8.8",
|
|
41
|
-
"react-native-inapp-inspector": "^1.1.
|
|
41
|
+
"react-native-inapp-inspector": "^1.1.8",
|
|
42
42
|
"react-test-renderer": "19.2.3",
|
|
43
43
|
"typescript": "^5.8.3"
|
|
44
44
|
},
|
|
@@ -10639,9 +10639,9 @@
|
|
|
10639
10639
|
}
|
|
10640
10640
|
},
|
|
10641
10641
|
"node_modules/react-native-inapp-inspector": {
|
|
10642
|
-
"version": "1.1.
|
|
10643
|
-
"resolved": "https://registry.npmjs.org/react-native-inapp-inspector/-/react-native-inapp-inspector-1.1.
|
|
10644
|
-
"integrity": "sha512-
|
|
10642
|
+
"version": "1.1.8",
|
|
10643
|
+
"resolved": "https://registry.npmjs.org/react-native-inapp-inspector/-/react-native-inapp-inspector-1.1.8.tgz",
|
|
10644
|
+
"integrity": "sha512-YxmzhE/qRz/KgGva4d0hrL5CpZKmNfAtxrUSTxNM+tD2D5ch686RwG9C+KyqqJvpfIBIxkZyBqoTp31NVGVgjA==",
|
|
10645
10645
|
"dev": true,
|
|
10646
10646
|
"license": "MIT",
|
|
10647
10647
|
"dependencies": {
|
package/example/package.json
CHANGED
package/package.json
CHANGED