react-native-inapp-inspector 2.2.8 → 2.3.0
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/android/src/main/java/com/inappinspector/NetworkInspectorModule.kt +22 -7
- package/dist/commonjs/components/AppHeaderLogo.js +45 -12
- package/dist/commonjs/components/BrandSquareIcon.js +92 -49
- package/dist/commonjs/components/EmptyState.d.ts +7 -2
- package/dist/commonjs/components/EmptyState.js +11 -5
- package/dist/commonjs/components/Inspector/AnalyticsTab.js +29 -18
- package/dist/commonjs/components/Inspector/ConsoleTab.js +6 -1
- package/dist/commonjs/components/Inspector/CrashDetail.js +43 -9
- package/dist/commonjs/components/Inspector/CrashTab.js +34 -3
- package/dist/commonjs/components/Inspector/DeviceInfoTab.js +80 -16
- package/dist/commonjs/components/Inspector/InspectorHeader.js +16 -3
- package/dist/commonjs/components/Inspector/NetworkDetail.js +3 -2
- package/dist/commonjs/components/Inspector/NetworkTab.js +103 -4
- package/dist/commonjs/components/Inspector/ReduxTab.js +19 -3
- package/dist/commonjs/components/Inspector/SettingsPanel.js +4 -4
- package/dist/commonjs/components/Inspector/StorageTab.js +19 -3
- package/dist/commonjs/components/JsonViewer.js +2 -0
- package/dist/commonjs/components/MetaAccordion.js +15 -3
- package/dist/commonjs/constants/version.d.ts +1 -1
- package/dist/commonjs/constants/version.js +1 -1
- package/dist/commonjs/customHooks/networkLogger.d.ts +3 -0
- package/dist/commonjs/customHooks/networkLogger.js +10 -1
- package/dist/commonjs/helpers/index.d.ts +6 -0
- package/dist/commonjs/helpers/index.js +196 -6
- package/dist/commonjs/helpers/searchQueryParser.js +62 -20
- package/dist/commonjs/i18n/index.d.ts +13 -0
- package/dist/commonjs/i18n/index.js +35 -2
- package/dist/commonjs/index.d.ts +3 -0
- package/dist/commonjs/index.js +80 -11
- package/dist/commonjs/native/NativeInspector.js +13 -0
- package/dist/commonjs/native/NativeNetworkInspector.d.ts +1 -1
- package/dist/commonjs/styles/AppColors.d.ts +4 -0
- package/dist/commonjs/styles/AppColors.js +11 -1
- package/dist/commonjs/styles/AppFonts.d.ts +11 -0
- package/dist/commonjs/styles/AppFonts.js +11 -1
- package/dist/commonjs/types/interfaces.d.ts +1 -0
- package/dist/esm/components/AppHeaderLogo.js +45 -12
- package/dist/esm/components/BrandSquareIcon.js +92 -49
- package/dist/esm/components/EmptyState.d.ts +7 -2
- package/dist/esm/components/EmptyState.js +11 -5
- package/dist/esm/components/Inspector/AnalyticsTab.js +30 -19
- package/dist/esm/components/Inspector/ConsoleTab.js +6 -1
- package/dist/esm/components/Inspector/CrashDetail.js +43 -9
- package/dist/esm/components/Inspector/CrashTab.js +34 -3
- package/dist/esm/components/Inspector/DeviceInfoTab.js +80 -16
- package/dist/esm/components/Inspector/InspectorHeader.js +17 -4
- package/dist/esm/components/Inspector/NetworkDetail.js +3 -2
- package/dist/esm/components/Inspector/NetworkTab.js +103 -4
- package/dist/esm/components/Inspector/ReduxTab.js +19 -3
- package/dist/esm/components/Inspector/SettingsPanel.js +4 -4
- package/dist/esm/components/Inspector/StorageTab.js +19 -3
- package/dist/esm/components/JsonViewer.js +2 -0
- package/dist/esm/components/MetaAccordion.js +15 -3
- package/dist/esm/constants/version.d.ts +1 -1
- package/dist/esm/constants/version.js +1 -1
- package/dist/esm/customHooks/networkLogger.d.ts +3 -0
- package/dist/esm/customHooks/networkLogger.js +8 -0
- package/dist/esm/helpers/index.d.ts +6 -0
- package/dist/esm/helpers/index.js +193 -5
- package/dist/esm/helpers/searchQueryParser.js +62 -20
- package/dist/esm/i18n/index.d.ts +13 -0
- package/dist/esm/i18n/index.js +33 -3
- package/dist/esm/index.d.ts +3 -0
- package/dist/esm/index.js +68 -12
- package/dist/esm/native/NativeInspector.js +13 -0
- package/dist/esm/native/NativeNetworkInspector.d.ts +1 -1
- package/dist/esm/styles/AppColors.d.ts +4 -0
- package/dist/esm/styles/AppColors.js +9 -0
- package/dist/esm/styles/AppFonts.d.ts +11 -0
- package/dist/esm/styles/AppFonts.js +9 -0
- package/dist/esm/types/interfaces.d.ts +1 -0
- package/ios/NetworkInspectorModule.mm +11 -1
- package/package.json +1 -1
- package/src/components/AppHeaderLogo.tsx +46 -12
- package/src/components/BrandSquareIcon.tsx +127 -78
- package/src/components/EmptyState.tsx +27 -5
- package/src/components/Inspector/AnalyticsTab.tsx +48 -27
- package/src/components/Inspector/ConsoleTab.tsx +10 -0
- package/src/components/Inspector/CrashDetail.tsx +65 -9
- package/src/components/Inspector/CrashTab.tsx +41 -3
- package/src/components/Inspector/DeviceInfoTab.tsx +87 -16
- package/src/components/Inspector/InspectorHeader.tsx +24 -4
- package/src/components/Inspector/NetworkDetail.tsx +4 -4
- package/src/components/Inspector/NetworkTab.tsx +129 -4
- package/src/components/Inspector/ReduxTab.tsx +26 -8
- package/src/components/Inspector/SettingsPanel.tsx +4 -4
- package/src/components/Inspector/StorageTab.tsx +21 -3
- package/src/components/JsonViewer.tsx +2 -0
- package/src/components/MetaAccordion.tsx +18 -3
- package/src/constants/version.ts +1 -1
- package/src/customHooks/networkLogger.ts +15 -0
- package/src/helpers/index.ts +213 -5
- package/src/helpers/searchQueryParser.ts +63 -20
- package/src/i18n/index.ts +38 -3
- package/src/index.tsx +89 -11
- package/src/native/NativeInspector.ts +13 -0
- package/src/native/NativeNetworkInspector.ts +1 -1
- package/src/styles/AppColors.ts +9 -0
- package/src/styles/AppFonts.ts +16 -0
- package/src/types/interfaces.ts +1 -0
|
@@ -60,9 +60,9 @@ const InfoRow = react_1.default.memo(({ label, value, copyable = true, badge, su
|
|
|
60
60
|
styles.infoRow,
|
|
61
61
|
isLast && { borderBottomWidth: 0 },
|
|
62
62
|
]}>
|
|
63
|
-
<react_native_1.View style={{ flex: 1, paddingRight: 8 }}>
|
|
64
|
-
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
|
|
65
|
-
<react_native_1.Text style={styles.infoLabel}>{label}</react_native_1.Text>
|
|
63
|
+
<react_native_1.View style={{ flex: 1, paddingRight: 8, minWidth: 0 }}>
|
|
64
|
+
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', flexWrap: 'wrap', gap: 6 }}>
|
|
65
|
+
<react_native_1.Text style={styles.infoLabel} numberOfLines={2}>{label}</react_native_1.Text>
|
|
66
66
|
{badge && (<react_native_1.View style={[
|
|
67
67
|
styles.infoBadge,
|
|
68
68
|
{ backgroundColor: badge.bg, borderColor: `${badge.color}33` },
|
|
@@ -72,15 +72,22 @@ const InfoRow = react_1.default.memo(({ label, value, copyable = true, badge, su
|
|
|
72
72
|
</react_native_1.Text>
|
|
73
73
|
</react_native_1.View>)}
|
|
74
74
|
</react_native_1.View>
|
|
75
|
-
{subtext && <react_native_1.Text style={styles.infoSubtext}>{subtext}</react_native_1.Text>}
|
|
75
|
+
{subtext && <react_native_1.Text style={styles.infoSubtext} numberOfLines={2}>{subtext}</react_native_1.Text>}
|
|
76
76
|
</react_native_1.View>
|
|
77
|
-
<react_native_1.View style={{
|
|
77
|
+
<react_native_1.View style={{
|
|
78
|
+
flexDirection: 'row',
|
|
79
|
+
alignItems: 'center',
|
|
80
|
+
gap: 6,
|
|
81
|
+
flexShrink: 0,
|
|
82
|
+
maxWidth: '58%',
|
|
83
|
+
justifyContent: 'flex-end',
|
|
84
|
+
}}>
|
|
78
85
|
<react_native_1.Text style={[
|
|
79
86
|
styles.infoValue,
|
|
80
87
|
typeof value === 'boolean' && {
|
|
81
88
|
color: value ? AppColors_1.AppColors.emerald500 : AppColors_1.AppColors.errorColor,
|
|
82
89
|
},
|
|
83
|
-
]} numberOfLines={
|
|
90
|
+
]} numberOfLines={3} selectable>
|
|
84
91
|
{displayValue}
|
|
85
92
|
</react_native_1.Text>
|
|
86
93
|
{copyable && value !== null && value !== undefined && (<TouchableScale_1.default hitSlop={8} onPress={() => {
|
|
@@ -387,6 +394,14 @@ exports.DeviceInfoTab = react_1.default.memo(() => {
|
|
|
387
394
|
return true;
|
|
388
395
|
return text.toLowerCase().includes(search.toLowerCase().trim());
|
|
389
396
|
};
|
|
397
|
+
const hasAnyMatch = (0, react_1.useMemo)(() => {
|
|
398
|
+
if (!search.trim())
|
|
399
|
+
return true;
|
|
400
|
+
const query = search.toLowerCase().trim();
|
|
401
|
+
return (JSON.stringify(fullDeviceData).toLowerCase().includes(query) ||
|
|
402
|
+
ipAddress.toLowerCase().includes(query) ||
|
|
403
|
+
pseudoUDID.toLowerCase().includes(query));
|
|
404
|
+
}, [search, fullDeviceData, ipAddress, pseudoUDID]);
|
|
390
405
|
return (<react_native_1.View style={styles.container}>
|
|
391
406
|
{/* ─── Top Sub-Tabs Navigation Bar ─── */}
|
|
392
407
|
<react_native_1.View style={styles.subTabsWrapper}>
|
|
@@ -436,11 +451,11 @@ exports.DeviceInfoTab = react_1.default.memo(() => {
|
|
|
436
451
|
<react_native_1.View style={styles.heroIconWrap}>
|
|
437
452
|
{react_native_1.Platform.OS === 'ios' ? (<NetworkIcons_1.AppleIcon size={20} color={AppColors_1.AppColors.white}/>) : (<NetworkIcons_1.AndroidIcon size={20} color={AppColors_1.AppColors.white}/>)}
|
|
438
453
|
</react_native_1.View>
|
|
439
|
-
<react_native_1.View style={{ flex: 1 }}>
|
|
440
|
-
<react_native_1.Text style={styles.heroTitle}>
|
|
454
|
+
<react_native_1.View style={{ flex: 1, minWidth: 0 }}>
|
|
455
|
+
<react_native_1.Text style={styles.heroTitle} numberOfLines={1} ellipsizeMode="tail">
|
|
441
456
|
{deviceMetrics?.deviceModel || react_native_1.Platform.constants?.Model || (react_native_1.Platform.OS === 'ios' ? 'Apple iPhone' : 'Android Device')}
|
|
442
457
|
</react_native_1.Text>
|
|
443
|
-
<react_native_1.Text style={styles.heroSubtitle}>
|
|
458
|
+
<react_native_1.Text style={styles.heroSubtitle} numberOfLines={1} ellipsizeMode="tail">
|
|
444
459
|
{react_native_1.Platform.OS === 'ios' ? `iOS ${react_native_1.Platform.Version}` : `Android ${react_native_1.Platform.Version} (API ${deviceMetrics?.apiLevel || react_native_1.Platform.Version})`}
|
|
445
460
|
</react_native_1.Text>
|
|
446
461
|
</react_native_1.View>
|
|
@@ -453,22 +468,22 @@ exports.DeviceInfoTab = react_1.default.memo(() => {
|
|
|
453
468
|
{/* Quick Metrics Strip */}
|
|
454
469
|
<react_native_1.View style={styles.heroMetricsStrip}>
|
|
455
470
|
<react_native_1.View style={styles.heroMetricItem}>
|
|
456
|
-
<react_native_1.Text style={styles.heroMetricLabel}>IP ADDRESS</react_native_1.Text>
|
|
457
|
-
<react_native_1.Text style={styles.heroMetricValue} numberOfLines={1}>
|
|
471
|
+
<react_native_1.Text style={styles.heroMetricLabel} numberOfLines={1} ellipsizeMode="tail">IP ADDRESS</react_native_1.Text>
|
|
472
|
+
<react_native_1.Text style={styles.heroMetricValue} numberOfLines={1} ellipsizeMode="tail">
|
|
458
473
|
{ipAddress}
|
|
459
474
|
</react_native_1.Text>
|
|
460
475
|
</react_native_1.View>
|
|
461
476
|
<react_native_1.View style={styles.heroMetricDivider}/>
|
|
462
477
|
<react_native_1.View style={styles.heroMetricItem}>
|
|
463
|
-
<react_native_1.Text style={styles.heroMetricLabel}>RAM (USED/TOTAL)</react_native_1.Text>
|
|
464
|
-
<react_native_1.Text style={styles.heroMetricValue}>
|
|
478
|
+
<react_native_1.Text style={styles.heroMetricLabel} numberOfLines={1} ellipsizeMode="tail">RAM (USED/TOTAL)</react_native_1.Text>
|
|
479
|
+
<react_native_1.Text style={styles.heroMetricValue} numberOfLines={1} ellipsizeMode="tail">
|
|
465
480
|
{usedRamMb}/{totalRamMb} MB
|
|
466
481
|
</react_native_1.Text>
|
|
467
482
|
</react_native_1.View>
|
|
468
483
|
<react_native_1.View style={styles.heroMetricDivider}/>
|
|
469
484
|
<react_native_1.View style={styles.heroMetricItem}>
|
|
470
|
-
<react_native_1.Text style={styles.heroMetricLabel}>UPTIME</react_native_1.Text>
|
|
471
|
-
<react_native_1.Text style={styles.heroMetricValue}>{deviceUptime}</react_native_1.Text>
|
|
485
|
+
<react_native_1.Text style={styles.heroMetricLabel} numberOfLines={1} ellipsizeMode="tail">UPTIME</react_native_1.Text>
|
|
486
|
+
<react_native_1.Text style={styles.heroMetricValue} numberOfLines={1} ellipsizeMode="tail">{deviceUptime}</react_native_1.Text>
|
|
472
487
|
</react_native_1.View>
|
|
473
488
|
</react_native_1.View>
|
|
474
489
|
</react_native_1.View>
|
|
@@ -581,6 +596,18 @@ exports.DeviceInfoTab = react_1.default.memo(() => {
|
|
|
581
596
|
{isMatch('Sandbox Integrity') && (<InfoRow label="App Sandbox File Isolation" value="Enforced by OS Kernel" isLast/>)}
|
|
582
597
|
</react_native_1.View>)}
|
|
583
598
|
|
|
599
|
+
{/* Empty search results state */}
|
|
600
|
+
{search.trim().length > 0 && !hasAnyMatch && (<react_native_1.View style={styles.emptySearchCard}>
|
|
601
|
+
<NetworkIcons_1.SearchIcon size={26} color={AppColors_1.AppColors.grayTextWeak}/>
|
|
602
|
+
<react_native_1.Text style={styles.emptySearchTitle}>No matching device specifications</react_native_1.Text>
|
|
603
|
+
<react_native_1.Text style={styles.emptySearchSubtitle}>
|
|
604
|
+
No properties matched “{search}”
|
|
605
|
+
</react_native_1.Text>
|
|
606
|
+
<TouchableScale_1.default onPress={() => setSearch('')} style={styles.clearSearchBtn}>
|
|
607
|
+
<react_native_1.Text style={styles.clearSearchBtnText}>Clear Search</react_native_1.Text>
|
|
608
|
+
</TouchableScale_1.default>
|
|
609
|
+
</react_native_1.View>)}
|
|
610
|
+
|
|
584
611
|
<react_native_1.View style={{ height: 48 }}/>
|
|
585
612
|
</react_native_1.ScrollView>
|
|
586
613
|
</react_native_1.View>);
|
|
@@ -752,6 +779,8 @@ const styles = react_native_1.StyleSheet.create({
|
|
|
752
779
|
heroMetricItem: {
|
|
753
780
|
flex: 1,
|
|
754
781
|
alignItems: 'center',
|
|
782
|
+
paddingHorizontal: 2,
|
|
783
|
+
minWidth: 0,
|
|
755
784
|
},
|
|
756
785
|
heroMetricLabel: {
|
|
757
786
|
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
@@ -823,7 +852,7 @@ const styles = react_native_1.StyleSheet.create({
|
|
|
823
852
|
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
824
853
|
fontSize: 12,
|
|
825
854
|
color: AppColors_1.AppColors.primaryBlack,
|
|
826
|
-
|
|
855
|
+
flexShrink: 1,
|
|
827
856
|
textAlign: 'right',
|
|
828
857
|
},
|
|
829
858
|
rowCopyBtn: {
|
|
@@ -831,5 +860,40 @@ const styles = react_native_1.StyleSheet.create({
|
|
|
831
860
|
borderRadius: 4,
|
|
832
861
|
backgroundColor: AppColors_1.AppColors.grayBackground,
|
|
833
862
|
},
|
|
863
|
+
emptySearchCard: {
|
|
864
|
+
backgroundColor: AppColors_1.AppColors.primaryLight,
|
|
865
|
+
borderRadius: 14,
|
|
866
|
+
borderWidth: 1,
|
|
867
|
+
borderColor: AppColors_1.AppColors.grayBorderSecondary,
|
|
868
|
+
padding: 24,
|
|
869
|
+
alignItems: 'center',
|
|
870
|
+
justifyContent: 'center',
|
|
871
|
+
gap: 8,
|
|
872
|
+
marginTop: 8,
|
|
873
|
+
},
|
|
874
|
+
emptySearchTitle: {
|
|
875
|
+
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
876
|
+
fontSize: 13.5,
|
|
877
|
+
color: AppColors_1.AppColors.primaryBlack,
|
|
878
|
+
textAlign: 'center',
|
|
879
|
+
},
|
|
880
|
+
emptySearchSubtitle: {
|
|
881
|
+
fontFamily: AppFonts_1.AppFonts.interRegular,
|
|
882
|
+
fontSize: 11.5,
|
|
883
|
+
color: AppColors_1.AppColors.grayTextWeak,
|
|
884
|
+
textAlign: 'center',
|
|
885
|
+
},
|
|
886
|
+
clearSearchBtn: {
|
|
887
|
+
marginTop: 6,
|
|
888
|
+
paddingHorizontal: 14,
|
|
889
|
+
paddingVertical: 6.5,
|
|
890
|
+
borderRadius: 8,
|
|
891
|
+
backgroundColor: AppColors_1.AppColors.purple,
|
|
892
|
+
},
|
|
893
|
+
clearSearchBtnText: {
|
|
894
|
+
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
895
|
+
fontSize: 11,
|
|
896
|
+
color: AppColors_1.AppColors.white,
|
|
897
|
+
},
|
|
834
898
|
});
|
|
835
899
|
exports.default = exports.DeviceInfoTab;
|
|
@@ -48,11 +48,26 @@ const AppFonts_1 = require("../../styles/AppFonts");
|
|
|
48
48
|
const constants_1 = require("../../constants");
|
|
49
49
|
const constants_2 = require("../../constants");
|
|
50
50
|
const helpers_1 = require("../../helpers");
|
|
51
|
+
const NativeInspector_1 = require("../../native/NativeInspector");
|
|
51
52
|
const UpdateAvailableModal_1 = require("./UpdateAvailableModal");
|
|
52
53
|
const NetworkIcons_1 = require("../NetworkIcons");
|
|
53
54
|
const InspectorHeader = react_1.default.memo(() => {
|
|
54
55
|
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, } = (0, InspectorContext_1.useInspector)();
|
|
55
56
|
const [showUpdateModal, setShowUpdateModal] = react_1.default.useState(false);
|
|
57
|
+
const [appVersionString, setAppVersionString] = react_1.default.useState(() => {
|
|
58
|
+
return (0, helpers_1.getAppVersionAndBuild)().formatted;
|
|
59
|
+
});
|
|
60
|
+
react_1.default.useEffect(() => {
|
|
61
|
+
(0, NativeInspector_1.getNativeDeviceMetrics)()
|
|
62
|
+
.then(metrics => {
|
|
63
|
+
if (metrics?.appVersion) {
|
|
64
|
+
const v = metrics.appVersion;
|
|
65
|
+
const b = metrics.appBuild || '1';
|
|
66
|
+
setAppVersionString(`${v} (${b})`);
|
|
67
|
+
}
|
|
68
|
+
})
|
|
69
|
+
.catch(() => { });
|
|
70
|
+
}, []);
|
|
56
71
|
const envConfig = (0, react_1.useMemo)(() => {
|
|
57
72
|
const rawEnv = (environment || (__DEV__ ? 'DEV' : 'PROD')).trim();
|
|
58
73
|
const clean = rawEnv.toUpperCase();
|
|
@@ -303,9 +318,7 @@ const InspectorHeader = react_1.default.memo(() => {
|
|
|
303
318
|
color: `${AppColors_1.AppColors.white}EB`,
|
|
304
319
|
letterSpacing: 0.1,
|
|
305
320
|
}} numberOfLines={1}>
|
|
306
|
-
{
|
|
307
|
-
? `iOS ${react_native_1.Platform.Version}`
|
|
308
|
-
: `Android ${react_native_1.Platform.Version}`}
|
|
321
|
+
{appVersionString}
|
|
309
322
|
</react_native_1.Text>
|
|
310
323
|
</react_native_1.View>
|
|
311
324
|
|
|
@@ -401,8 +401,9 @@ const NetworkDetail = react_1.default.memo(() => {
|
|
|
401
401
|
selected.responseHeaders?.['Content-Type']} url={selected.url}/>
|
|
402
402
|
|
|
403
403
|
{(() => {
|
|
404
|
-
const routeInfo = logRouteMapRef.current.get(selected.id)
|
|
405
|
-
|
|
404
|
+
const routeInfo = logRouteMapRef.current.get(selected.id) ||
|
|
405
|
+
selected?.routeInfo;
|
|
406
|
+
if (!routeInfo || !routeInfo.path || routeInfo.path === 'Navigators')
|
|
406
407
|
return null;
|
|
407
408
|
return <SourcePageCard_1.default routeInfo={routeInfo}/>;
|
|
408
409
|
})()}
|
|
@@ -507,7 +507,7 @@ const NetworkTab = react_1.default.memo(() => {
|
|
|
507
507
|
<react_native_1.View style={{
|
|
508
508
|
backgroundColor: `${AppColors_1.AppColors.purple}20`,
|
|
509
509
|
borderRadius: 10,
|
|
510
|
-
paddingHorizontal:
|
|
510
|
+
paddingHorizontal: 6,
|
|
511
511
|
paddingVertical: 1.5,
|
|
512
512
|
}}>
|
|
513
513
|
<react_native_1.Text style={{
|
|
@@ -560,14 +560,104 @@ const NetworkTab = react_1.default.memo(() => {
|
|
|
560
560
|
styles_1.default.toolbarBtn,
|
|
561
561
|
filtersAccordion.isOpen &&
|
|
562
562
|
styles_1.default.toolbarBtnActive,
|
|
563
|
-
]} onPress={filtersAccordion.toggleOpen} hitSlop={
|
|
563
|
+
]} onPress={filtersAccordion.toggleOpen} hitSlop={6}>
|
|
564
564
|
<NetworkIcons_1.FilterIcon color={filtersAccordion.isOpen
|
|
565
565
|
? AppColors_1.AppColors.purple
|
|
566
|
-
: AppColors_1.AppColors.grayTextStrong} size={
|
|
566
|
+
: AppColors_1.AppColors.grayTextStrong} size={16}/>
|
|
567
|
+
{(statusFilters.size > 0 ||
|
|
568
|
+
methodFilters.size > 0) && (<react_native_1.View style={styles_1.default.activeFilterDot}/>)}
|
|
567
569
|
</TouchableScale_1.default>
|
|
568
570
|
</react_native_1.View>
|
|
569
571
|
</react_native_1.View>
|
|
570
572
|
|
|
573
|
+
{/* Quick Search Scope & Filter Tags Row */}
|
|
574
|
+
<react_native_1.View style={{ paddingBottom: 4 }}>
|
|
575
|
+
<react_native_1.ScrollView horizontal showsHorizontalScrollIndicator={false} contentContainerStyle={{
|
|
576
|
+
paddingHorizontal: 12,
|
|
577
|
+
flexDirection: 'row',
|
|
578
|
+
alignItems: 'center',
|
|
579
|
+
gap: 5,
|
|
580
|
+
paddingVertical: 2,
|
|
581
|
+
}}>
|
|
582
|
+
{/* Search Scopes */}
|
|
583
|
+
{SEARCH_SCOPES.map(s => {
|
|
584
|
+
const isActive = searchScope === s.id;
|
|
585
|
+
return (<TouchableScale_1.default key={`scope_${s.id}`} onPress={() => setSearchScope(s.id)} hitSlop={6} style={{
|
|
586
|
+
flexDirection: 'row',
|
|
587
|
+
alignItems: 'center',
|
|
588
|
+
gap: 3.5,
|
|
589
|
+
paddingHorizontal: 7.5,
|
|
590
|
+
paddingVertical: 3.5,
|
|
591
|
+
borderRadius: 6,
|
|
592
|
+
backgroundColor: isActive
|
|
593
|
+
? AppColors_1.AppColors.purple
|
|
594
|
+
: AppColors_1.AppColors.grayBackground,
|
|
595
|
+
borderWidth: 1,
|
|
596
|
+
borderColor: isActive
|
|
597
|
+
? AppColors_1.AppColors.purple
|
|
598
|
+
: AppColors_1.AppColors.grayBorderSecondary,
|
|
599
|
+
}}>
|
|
600
|
+
{s.icon(isActive ? AppColors_1.AppColors.white : AppColors_1.AppColors.grayTextWeak)}
|
|
601
|
+
<react_native_1.Text style={{
|
|
602
|
+
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
603
|
+
fontSize: 10,
|
|
604
|
+
color: isActive ? AppColors_1.AppColors.white : AppColors_1.AppColors.grayText,
|
|
605
|
+
}}>
|
|
606
|
+
{s.label}
|
|
607
|
+
</react_native_1.Text>
|
|
608
|
+
</TouchableScale_1.default>);
|
|
609
|
+
})}
|
|
610
|
+
|
|
611
|
+
<react_native_1.View style={{
|
|
612
|
+
width: 1,
|
|
613
|
+
height: 14,
|
|
614
|
+
backgroundColor: AppColors_1.AppColors.dividerColor,
|
|
615
|
+
marginHorizontal: 3,
|
|
616
|
+
}}/>
|
|
617
|
+
|
|
618
|
+
{/* Quick Query Suggestions */}
|
|
619
|
+
{QUICK_API_QUERY_TAGS.map(q => {
|
|
620
|
+
const isActive = search.includes(q.query);
|
|
621
|
+
return (<TouchableScale_1.default key={`quick_${q.query}`} onPress={() => {
|
|
622
|
+
setSearch(prev => {
|
|
623
|
+
if (prev.includes(q.query)) {
|
|
624
|
+
return prev
|
|
625
|
+
.replace(q.query, '')
|
|
626
|
+
.replace(/\s+/g, ' ')
|
|
627
|
+
.trim();
|
|
628
|
+
}
|
|
629
|
+
return `${prev} ${q.query}`.trim();
|
|
630
|
+
});
|
|
631
|
+
}} hitSlop={6} style={{
|
|
632
|
+
flexDirection: 'row',
|
|
633
|
+
alignItems: 'center',
|
|
634
|
+
gap: 3.5,
|
|
635
|
+
paddingHorizontal: 7.5,
|
|
636
|
+
paddingVertical: 3.5,
|
|
637
|
+
borderRadius: 6,
|
|
638
|
+
backgroundColor: isActive
|
|
639
|
+
? `${AppColors_1.AppColors.purple}20`
|
|
640
|
+
: AppColors_1.AppColors.grayBackground,
|
|
641
|
+
borderWidth: 1,
|
|
642
|
+
borderColor: isActive
|
|
643
|
+
? AppColors_1.AppColors.purple
|
|
644
|
+
: AppColors_1.AppColors.grayBorderSecondary,
|
|
645
|
+
}}>
|
|
646
|
+
{q.icon(isActive ? AppColors_1.AppColors.purple : AppColors_1.AppColors.grayTextWeak)}
|
|
647
|
+
<react_native_1.Text style={{
|
|
648
|
+
fontFamily: AppFonts_1.AppFonts.interMedium,
|
|
649
|
+
fontSize: 10,
|
|
650
|
+
color: isActive
|
|
651
|
+
? AppColors_1.AppColors.purple
|
|
652
|
+
: AppColors_1.AppColors.grayText,
|
|
653
|
+
}}>
|
|
654
|
+
{q.label}
|
|
655
|
+
</react_native_1.Text>
|
|
656
|
+
</TouchableScale_1.default>);
|
|
657
|
+
})}
|
|
658
|
+
</react_native_1.ScrollView>
|
|
659
|
+
</react_native_1.View>
|
|
660
|
+
|
|
571
661
|
{/* Quick Filter Horizontal Chips Bar with Live Counts */}
|
|
572
662
|
<react_native_1.View style={{ marginBottom: 8 }}>
|
|
573
663
|
<react_native_1.ScrollView horizontal showsHorizontalScrollIndicator={false} contentContainerStyle={{
|
|
@@ -853,7 +943,16 @@ const NetworkTab = react_1.default.memo(() => {
|
|
|
853
943
|
? `${logs.length} requests`
|
|
854
944
|
: `${filteredLogs.length} of ${logs.length} filtered requests`}
|
|
855
945
|
</react_native_1.Text>)}
|
|
856
|
-
</react_native_1.View>} ListEmptyComponent={<EmptyState_1.default isSearch={search.length > 0 ||
|
|
946
|
+
</react_native_1.View>} ListEmptyComponent={<EmptyState_1.default isSearch={search.length > 0 ||
|
|
947
|
+
statusFilters.size > 0 ||
|
|
948
|
+
methodFilters.size > 0} searchQuery={search} customTitle={search.length > 0
|
|
949
|
+
? 'No matching API requests'
|
|
950
|
+
: 'No network activity'} onClearSearch={() => {
|
|
951
|
+
setSearch('');
|
|
952
|
+
setStatusFilters(new Set());
|
|
953
|
+
setMethodFilters(new Set());
|
|
954
|
+
setSearchScope('all');
|
|
955
|
+
}}/>} ListFooterComponent={groupedData.length > 0 ? (<EndOfListFooter_1.default count={filteredLogs.length} label="requests"/>) : null} contentContainerStyle={[
|
|
857
956
|
styles_1.default.listContent,
|
|
858
957
|
filteredLogs.length === 0 && { flexGrow: 1 },
|
|
859
958
|
]} keyboardShouldPersistTaps="handled"/>
|
|
@@ -434,9 +434,25 @@ const ReduxTab = react_1.default.memo(() => {
|
|
|
434
434
|
<react_native_1.View style={styles_1.default.searchContainer}>
|
|
435
435
|
<NetworkIcons_1.SearchIcon color={AppColors_1.AppColors.grayTextWeak} size={15}/>
|
|
436
436
|
<react_native_1.TextInput accessible={true} accessibilityRole="search" accessibilityLabel="Search Redux slices or actions" accessibilityHint="Type to filter state slices in real time" placeholder="Search Redux slices or actions..." placeholderTextColor={AppColors_1.AppColors.grayTextWeak} value={reduxSearch} onChangeText={setReduxSearch} style={styles_1.default.searchInput} autoCorrect={false} autoCapitalize="none"/>
|
|
437
|
-
{reduxSearch.length > 0 && (<react_native_1.
|
|
438
|
-
<
|
|
439
|
-
|
|
437
|
+
{reduxSearch.length > 0 && (<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 4 }}>
|
|
438
|
+
<react_native_1.View style={{
|
|
439
|
+
backgroundColor: `${AppColors_1.AppColors.purple}20`,
|
|
440
|
+
borderRadius: 10,
|
|
441
|
+
paddingHorizontal: 6,
|
|
442
|
+
paddingVertical: 1.5,
|
|
443
|
+
}}>
|
|
444
|
+
<react_native_1.Text style={{
|
|
445
|
+
color: AppColors_1.AppColors.purple,
|
|
446
|
+
fontSize: 9.5,
|
|
447
|
+
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
448
|
+
}}>
|
|
449
|
+
{filteredSlices.length}
|
|
450
|
+
</react_native_1.Text>
|
|
451
|
+
</react_native_1.View>
|
|
452
|
+
<react_native_1.Pressable accessible={true} accessibilityRole="button" accessibilityLabel="Clear search input" onPress={() => setReduxSearch('')} hitSlop={10}>
|
|
453
|
+
<NetworkIcons_1.ClearIcon color={AppColors_1.AppColors.grayTextWeak} size={14}/>
|
|
454
|
+
</react_native_1.Pressable>
|
|
455
|
+
</react_native_1.View>)}
|
|
440
456
|
</react_native_1.View>
|
|
441
457
|
|
|
442
458
|
{/* Pause / Resume Live Updates Button */}
|
|
@@ -146,8 +146,8 @@ const SettingsPanel = () => {
|
|
|
146
146
|
bundle: Boolean(tabVisibility?.bundle),
|
|
147
147
|
performance: Boolean(tabVisibility?.performance),
|
|
148
148
|
crash: Boolean(tabVisibility?.crash),
|
|
149
|
-
device: Boolean(tabVisibility?.device
|
|
150
|
-
storage: Boolean(tabVisibility?.storage
|
|
149
|
+
device: Boolean(tabVisibility?.device),
|
|
150
|
+
storage: Boolean(tabVisibility?.storage),
|
|
151
151
|
}));
|
|
152
152
|
// Synchronize staged state with tabVisibility when tabVisibility updates
|
|
153
153
|
(0, react_1.useEffect)(() => {
|
|
@@ -159,8 +159,8 @@ const SettingsPanel = () => {
|
|
|
159
159
|
bundle: Boolean(tabVisibility?.bundle),
|
|
160
160
|
performance: Boolean(tabVisibility?.performance),
|
|
161
161
|
crash: Boolean(tabVisibility?.crash),
|
|
162
|
-
device: Boolean(tabVisibility?.device
|
|
163
|
-
storage: Boolean(tabVisibility?.storage
|
|
162
|
+
device: Boolean(tabVisibility?.device),
|
|
163
|
+
storage: Boolean(tabVisibility?.storage),
|
|
164
164
|
});
|
|
165
165
|
}, [tabVisibility]);
|
|
166
166
|
const hasUnsavedChanges = (0, react_1.useMemo)(() => {
|
|
@@ -284,9 +284,25 @@ exports.StorageTab = react_1.default.memo(() => {
|
|
|
284
284
|
<react_native_1.View style={styles.searchBar}>
|
|
285
285
|
<NetworkIcons_1.SearchIcon size={14} color={AppColors_1.AppColors.grayTextWeak}/>
|
|
286
286
|
<react_native_1.TextInput value={search} onChangeText={setSearch} placeholder={`Search ${entries.length} keys & values...`} placeholderTextColor={AppColors_1.AppColors.grayTextWeak} style={styles.searchInput} clearButtonMode="while-editing"/>
|
|
287
|
-
{search.length > 0 && (<
|
|
288
|
-
<
|
|
289
|
-
|
|
287
|
+
{search.length > 0 && (<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 4 }}>
|
|
288
|
+
<react_native_1.View style={{
|
|
289
|
+
backgroundColor: `${AppColors_1.AppColors.purple}20`,
|
|
290
|
+
borderRadius: 10,
|
|
291
|
+
paddingHorizontal: 6,
|
|
292
|
+
paddingVertical: 1.5,
|
|
293
|
+
}}>
|
|
294
|
+
<react_native_1.Text style={{
|
|
295
|
+
color: AppColors_1.AppColors.purple,
|
|
296
|
+
fontSize: 9.5,
|
|
297
|
+
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
298
|
+
}}>
|
|
299
|
+
{filteredEntries.length}
|
|
300
|
+
</react_native_1.Text>
|
|
301
|
+
</react_native_1.View>
|
|
302
|
+
<TouchableScale_1.default onPress={() => setSearch('')} hitSlop={8}>
|
|
303
|
+
<NetworkIcons_1.ClearIcon size={13} color={AppColors_1.AppColors.grayTextWeak}/>
|
|
304
|
+
</TouchableScale_1.default>
|
|
305
|
+
</react_native_1.View>)}
|
|
290
306
|
</react_native_1.View>
|
|
291
307
|
|
|
292
308
|
{/* Action Buttons: Add Key & Refresh */}
|
|
@@ -43,6 +43,7 @@ const i18n_1 = require("../i18n");
|
|
|
43
43
|
const TreeNode_1 = __importDefault(require("./TreeNode"));
|
|
44
44
|
const SegmentedTabs_1 = __importDefault(require("./SegmentedTabs"));
|
|
45
45
|
const HighlightText_1 = __importDefault(require("./HighlightText"));
|
|
46
|
+
const CopyButton_1 = __importDefault(require("./CopyButton"));
|
|
46
47
|
const NetworkIcons_1 = require("./NetworkIcons");
|
|
47
48
|
// Styles
|
|
48
49
|
const AppColors_1 = require("../styles/AppColors");
|
|
@@ -189,6 +190,7 @@ const JsonViewer = react_1.default.memo(({ data, search, forceOpen, defaultExpan
|
|
|
189
190
|
icon: (isActive) => (<NetworkIcons_1.TableIcon color={isActive ? AppColors_1.AppColors.white : AppColors_1.AppColors.slate400} size={12}/>),
|
|
190
191
|
},
|
|
191
192
|
]} activeKey={mode} onChange={key => setMode(key)}/>
|
|
193
|
+
<CopyButton_1.default value={data} label="JSON"/>
|
|
192
194
|
</react_native_1.View>)}
|
|
193
195
|
|
|
194
196
|
{/* ── Main View Content Area (Royal Monospace Theme) ── */}
|
|
@@ -49,6 +49,7 @@ const helpers_1 = require("../helpers");
|
|
|
49
49
|
const NetworkIcons_1 = require("./NetworkIcons");
|
|
50
50
|
// Components
|
|
51
51
|
const TouchableScale_1 = __importDefault(require("./TouchableScale"));
|
|
52
|
+
const CopyButton_1 = __importDefault(require("./CopyButton"));
|
|
52
53
|
// Stylesheet
|
|
53
54
|
const AppColors_1 = require("../styles/AppColors");
|
|
54
55
|
const AppFonts_1 = require("../styles/AppFonts");
|
|
@@ -98,9 +99,20 @@ const MetaAccordion = ({ status, statusColor, duration, size, triggeredAt, metho
|
|
|
98
99
|
<react_native_1.Pressable onPress={toggleOpen} hitSlop={12}>
|
|
99
100
|
<react_native_1.View style={styles_1.default.metaHeader}>
|
|
100
101
|
<react_native_1.Text style={styles_1.default.metaTitle}>Metadata</react_native_1.Text>
|
|
101
|
-
<react_native_1.
|
|
102
|
-
<
|
|
103
|
-
|
|
102
|
+
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}>
|
|
103
|
+
<CopyButton_1.default value={{
|
|
104
|
+
status: status ?? 0,
|
|
105
|
+
duration: duration != null ? `${duration} ms` : '—',
|
|
106
|
+
size: size || '—',
|
|
107
|
+
triggeredAt: triggeredAt || '',
|
|
108
|
+
method: method || 'GET',
|
|
109
|
+
contentType: contentType || 'application/json',
|
|
110
|
+
url: url || '',
|
|
111
|
+
}} label="Metadata"/>
|
|
112
|
+
<react_native_1.Animated.View style={chevronStyle}>
|
|
113
|
+
<NetworkIcons_1.ChevronIcon color={AppColors_1.AppColors.grayTextWeak} size={14}/>
|
|
114
|
+
</react_native_1.Animated.View>
|
|
115
|
+
</react_native_1.View>
|
|
104
116
|
</react_native_1.View>
|
|
105
117
|
</react_native_1.Pressable>
|
|
106
118
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const LIB_VERSION = "2.
|
|
1
|
+
export declare const LIB_VERSION = "2.3.0";
|
|
@@ -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 = '2.
|
|
6
|
+
exports.LIB_VERSION = '2.3.0';
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { RouteInfo } from "../types";
|
|
1
2
|
type NetworkLog = {
|
|
2
3
|
id: number;
|
|
3
4
|
url: string;
|
|
@@ -11,7 +12,9 @@ type NetworkLog = {
|
|
|
11
12
|
client?: string;
|
|
12
13
|
requestHeaders?: Record<string, string>;
|
|
13
14
|
responseHeaders?: Record<string, string>;
|
|
15
|
+
routeInfo?: RouteInfo;
|
|
14
16
|
};
|
|
17
|
+
export declare const setRouteInfoProvider: (provider: (() => RouteInfo | null) | null) => void;
|
|
15
18
|
export declare const setNetworkModuleEnabled: (enabled: boolean) => void;
|
|
16
19
|
export declare const getNetworkModuleEnabled: () => boolean;
|
|
17
20
|
export declare const subscribeNetworkLogs: (callback: (logs: NetworkLog[]) => void) => () => void;
|
|
@@ -3,13 +3,18 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.addAxiosInterceptors = exports.setupNetworkLogger = exports.pruneNetworkLogs = exports.getMaxNetworkLogsLimit = exports.setMaxNetworkLogsLimit = exports.getNetworkLogs = exports.clearNetworkLogs = exports.subscribeNetworkLogs = exports.getNetworkModuleEnabled = exports.setNetworkModuleEnabled = void 0;
|
|
6
|
+
exports.addAxiosInterceptors = exports.setupNetworkLogger = exports.pruneNetworkLogs = exports.getMaxNetworkLogsLimit = exports.setMaxNetworkLogsLimit = exports.getNetworkLogs = exports.clearNetworkLogs = exports.subscribeNetworkLogs = exports.getNetworkModuleEnabled = exports.setNetworkModuleEnabled = exports.setRouteInfoProvider = void 0;
|
|
7
7
|
const axios_1 = __importDefault(require("axios"));
|
|
8
8
|
const crashHandler_1 = require("./crashHandler");
|
|
9
9
|
let logs = [];
|
|
10
10
|
let listeners = [];
|
|
11
11
|
let counter = 0;
|
|
12
12
|
let isNetworkModuleEnabled = true;
|
|
13
|
+
let currentRouteProvider = null;
|
|
14
|
+
const setRouteInfoProvider = (provider) => {
|
|
15
|
+
currentRouteProvider = provider;
|
|
16
|
+
};
|
|
17
|
+
exports.setRouteInfoProvider = setRouteInfoProvider;
|
|
13
18
|
const setNetworkModuleEnabled = (enabled) => {
|
|
14
19
|
isNetworkModuleEnabled = enabled;
|
|
15
20
|
};
|
|
@@ -199,6 +204,7 @@ const setupNetworkLogger = () => {
|
|
|
199
204
|
else if (caller?.toLowerCase().includes('axios')) {
|
|
200
205
|
client = 'axios';
|
|
201
206
|
}
|
|
207
|
+
const currentRoute = currentRouteProvider ? currentRouteProvider() : null;
|
|
202
208
|
addOrUpdateLog({
|
|
203
209
|
id,
|
|
204
210
|
url: finalUrl,
|
|
@@ -206,6 +212,7 @@ const setupNetworkLogger = () => {
|
|
|
206
212
|
startTime: start,
|
|
207
213
|
caller,
|
|
208
214
|
client,
|
|
215
|
+
routeInfo: currentRoute || undefined,
|
|
209
216
|
request: method === "GET" ? undefined : parseRequestData(options?.body),
|
|
210
217
|
requestHeaders,
|
|
211
218
|
});
|
|
@@ -313,6 +320,7 @@ const addAxiosInterceptors = (axiosInstance) => {
|
|
|
313
320
|
config.__logId = id;
|
|
314
321
|
config.__logStart = start;
|
|
315
322
|
config.__logCaller = caller;
|
|
323
|
+
const currentRoute = currentRouteProvider ? currentRouteProvider() : null;
|
|
316
324
|
addOrUpdateLog({
|
|
317
325
|
id,
|
|
318
326
|
url,
|
|
@@ -320,6 +328,7 @@ const addAxiosInterceptors = (axiosInstance) => {
|
|
|
320
328
|
startTime: start,
|
|
321
329
|
caller,
|
|
322
330
|
client: 'axios',
|
|
331
|
+
routeInfo: currentRoute || undefined,
|
|
323
332
|
request: method === "GET" ? undefined : parseRequestData(config.data),
|
|
324
333
|
requestHeaders: normaliseHeaders(config.headers),
|
|
325
334
|
});
|
|
@@ -15,6 +15,7 @@ export declare const getFetchCommand: (log: NetworkLog) => string;
|
|
|
15
15
|
export declare const deduplicateLogs: (raw: NetworkLog[]) => NetworkLog[];
|
|
16
16
|
export declare const escapeRegex: (str: string) => string;
|
|
17
17
|
export declare const getNavigationInfo: (state: any, path?: string[]) => RouteInfo;
|
|
18
|
+
export declare const getLogPageName: (log: NetworkLog, routeInfo?: RouteInfo | null) => string;
|
|
18
19
|
export declare const flattenObject: (obj: any, prefix?: string) => Record<string, any>;
|
|
19
20
|
export declare const getDiff: (oldObj: any, newObj: any) => DiffResult[];
|
|
20
21
|
export declare const formatDisplayUrl: (url: string) => string;
|
|
@@ -24,6 +25,11 @@ export declare const isAllValuesEmpty: (obj: Record<string, any>) => boolean;
|
|
|
24
25
|
export declare const formatDateTimeToAnalytics: (ts: number) => string;
|
|
25
26
|
export declare const getBundleIdentifier: () => string;
|
|
26
27
|
export declare const getAppName: () => string;
|
|
28
|
+
export declare const getAppVersionAndBuild: () => {
|
|
29
|
+
version: string;
|
|
30
|
+
build: string;
|
|
31
|
+
formatted: string;
|
|
32
|
+
};
|
|
27
33
|
export declare const handleOpenExternalLink: (url: string) => void;
|
|
28
34
|
/** Formats a timestamp as HH:MM:SS (no milliseconds). */
|
|
29
35
|
export declare const formatTimeShort: (ts: number) => string;
|