react-native-inapp-inspector 2.2.9 → 2.3.1
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/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/MainScreen.js +7 -11
- 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 +123 -92
- package/dist/commonjs/components/JsonViewer.js +2 -0
- package/dist/commonjs/components/MetaAccordion.js +15 -3
- package/dist/commonjs/components/SkeletonPlaceholder.d.ts +6 -0
- package/dist/commonjs/components/SkeletonPlaceholder.js +208 -0
- 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/customHooks/storageInspector.d.ts +2 -2
- package/dist/commonjs/customHooks/storageInspector.js +17 -13
- 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 +108 -35
- 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 +2 -2
- 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/MainScreen.js +8 -12
- 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 +124 -93
- package/dist/esm/components/JsonViewer.js +2 -0
- package/dist/esm/components/MetaAccordion.js +15 -3
- package/dist/esm/components/SkeletonPlaceholder.d.ts +6 -0
- package/dist/esm/components/SkeletonPlaceholder.js +173 -0
- 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/customHooks/storageInspector.d.ts +2 -2
- package/dist/esm/customHooks/storageInspector.js +17 -13
- 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 +97 -37
- 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 +2 -2
- 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/MainScreen.tsx +7 -11
- 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 +191 -117
- package/src/components/JsonViewer.tsx +2 -0
- package/src/components/MetaAccordion.tsx +18 -3
- package/src/components/SkeletonPlaceholder.tsx +206 -0
- package/src/constants/version.ts +1 -1
- package/src/customHooks/networkLogger.ts +15 -0
- package/src/customHooks/storageInspector.ts +18 -14
- 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 +124 -37
- package/src/styles/AppColors.ts +9 -0
- package/src/styles/AppFonts.ts +16 -0
- package/src/types/interfaces.ts +2 -2
|
@@ -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
|
|
|
@@ -49,6 +49,7 @@ const LogDetail_1 = __importDefault(require("./LogDetail"));
|
|
|
49
49
|
const ConsoleTab_1 = __importDefault(require("./ConsoleTab"));
|
|
50
50
|
const AnalyticsTab_1 = __importDefault(require("./AnalyticsTab"));
|
|
51
51
|
const AnalyticsDetail_1 = __importDefault(require("../AnalyticsDetail"));
|
|
52
|
+
const SkeletonPlaceholder_1 = __importDefault(require("../SkeletonPlaceholder"));
|
|
52
53
|
const ReduxTab_1 = __importDefault(require("./ReduxTab"));
|
|
53
54
|
const ReduxDetail_1 = __importDefault(require("./ReduxDetail"));
|
|
54
55
|
const BundleTab_1 = __importDefault(require("./BundleTab"));
|
|
@@ -64,7 +65,7 @@ const styles_1 = __importDefault(require("../../styles"));
|
|
|
64
65
|
const AppColors_1 = require("../../styles/AppColors");
|
|
65
66
|
const NavigationTracker_1 = __importDefault(require("./NavigationTracker"));
|
|
66
67
|
const MainScreen = () => {
|
|
67
|
-
const { visible, modalAnimationType, closeModal, modalHeightPercent, selected, selectedEvent, selectedLog, selectedReduxSlice, selectedReduxAction, selectedCrash, settingsPage, activeTab, isReady,
|
|
68
|
+
const { visible, modalAnimationType, closeModal, modalHeightPercent, selected, selectedEvent, selectedLog, selectedReduxSlice, selectedReduxAction, selectedCrash, settingsPage, activeTab, isReady, enabled, useNativeFab, hasNavigationContext, setNavState, } = (0, InspectorContext_1.useInspector)();
|
|
68
69
|
const isDetailActive = (activeTab === 'apis' && selected != null) ||
|
|
69
70
|
(activeTab === 'analytics' && selectedEvent != null) ||
|
|
70
71
|
(activeTab === 'logs' && selectedLog != null) ||
|
|
@@ -106,7 +107,7 @@ const MainScreen = () => {
|
|
|
106
107
|
}, [activeTab]);
|
|
107
108
|
return (<>
|
|
108
109
|
{(react_native_1.Platform.OS === 'ios' || react_native_1.Platform.OS === 'android') &&
|
|
109
|
-
|
|
110
|
+
enabled &&
|
|
110
111
|
!visible &&
|
|
111
112
|
!useNativeFab && <FabLauncher_1.default />}
|
|
112
113
|
<react_native_1.Modal visible={visible} animationType={modalAnimationType} transparent statusBarTranslucent={true}>
|
|
@@ -126,10 +127,10 @@ const MainScreen = () => {
|
|
|
126
127
|
<InspectorHeader_1.default />
|
|
127
128
|
|
|
128
129
|
<react_native_1.View style={{ flex: 1 }}>
|
|
129
|
-
{
|
|
130
|
-
|
|
131
|
-
{!isDetailActive && <TabBar_1.default />}
|
|
130
|
+
{/* ─── Horizontal Scrollable Tab Bar inside Content (Always visible) ─── */}
|
|
131
|
+
{!isDetailActive && <TabBar_1.default />}
|
|
132
132
|
|
|
133
|
+
{isReady ? (<react_native_1.View style={{ flex: 1 }}>
|
|
133
134
|
{/* Persistent List Layer - Never unmounted, preserves 100% native scroll with smooth tab transition */}
|
|
134
135
|
<react_native_1.Animated.View style={[
|
|
135
136
|
{
|
|
@@ -181,12 +182,7 @@ const MainScreen = () => {
|
|
|
181
182
|
{activeTab === 'redux' && <ReduxDetail_1.default />}
|
|
182
183
|
{activeTab === 'crash' && selectedCrash != null && (<CrashDetail_1.default />)}
|
|
183
184
|
</react_native_1.Animated.View>)}
|
|
184
|
-
</react_native_1.View>) : (<
|
|
185
|
-
<react_native_1.ActivityIndicator size="large" color={AppColors_1.AppColors.purple}/>
|
|
186
|
-
<react_native_1.Text style={[styles_1.default.emptySub, { marginTop: 12 }]}>
|
|
187
|
-
Loading logs...
|
|
188
|
-
</react_native_1.Text>
|
|
189
|
-
</react_native_1.View>)}
|
|
185
|
+
</react_native_1.View>) : (<SkeletonPlaceholder_1.default />)}
|
|
190
186
|
|
|
191
187
|
{/* Settings Panel Layer - Rendered on top with smooth slide & spring transition */}
|
|
192
188
|
{settingsPage !== null && (<react_native_1.Animated.View style={[
|
|
@@ -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)(() => {
|