react-native-inapp-inspector 2.3.14 → 2.3.15
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/AnimatedEntrance.js +3 -3
- package/dist/commonjs/components/ConsoleLogCard.js +174 -100
- package/dist/commonjs/components/Inspector/ConsoleTab.js +25 -16
- package/dist/commonjs/components/Inspector/CrashTab.js +19 -5
- package/dist/commonjs/components/Inspector/DeviceInfoTab.js +198 -98
- package/dist/commonjs/components/Inspector/InspectorHeader.js +2 -2
- package/dist/commonjs/components/Inspector/MainScreen.js +56 -56
- package/dist/commonjs/components/Inspector/NetworkTab.js +1 -335
- package/dist/commonjs/components/Inspector/PerformanceTab.js +32 -6
- package/dist/commonjs/components/Inspector/ReduxTab.js +3 -1
- package/dist/commonjs/components/Inspector/StorageTab.js +23 -5
- package/dist/commonjs/components/JsonViewer.js +14 -2
- package/dist/commonjs/components/LogCard.js +428 -227
- package/dist/commonjs/constants/version.d.ts +1 -1
- package/dist/commonjs/constants/version.js +1 -1
- package/dist/commonjs/customHooks/analyticsLogger.js +1 -1
- package/dist/commonjs/customHooks/consoleLogger.js +34 -2
- package/dist/commonjs/customHooks/crashHandler.js +1 -1
- package/dist/commonjs/customHooks/networkLogger.js +184 -26
- package/dist/commonjs/helpers/searchQueryParser.d.ts +1 -1
- package/dist/commonjs/helpers/searchQueryParser.js +37 -291
- package/dist/commonjs/index.js +141 -27
- package/dist/esm/components/AnimatedEntrance.js +3 -3
- package/dist/esm/components/ConsoleLogCard.js +141 -100
- package/dist/esm/components/Inspector/ConsoleTab.js +25 -16
- package/dist/esm/components/Inspector/CrashTab.js +19 -5
- package/dist/esm/components/Inspector/DeviceInfoTab.js +198 -98
- package/dist/esm/components/Inspector/InspectorHeader.js +3 -3
- package/dist/esm/components/Inspector/MainScreen.js +56 -56
- package/dist/esm/components/Inspector/NetworkTab.js +2 -336
- package/dist/esm/components/Inspector/PerformanceTab.js +32 -6
- package/dist/esm/components/Inspector/ReduxTab.js +3 -1
- package/dist/esm/components/Inspector/StorageTab.js +23 -5
- package/dist/esm/components/JsonViewer.js +14 -2
- package/dist/esm/components/LogCard.js +422 -221
- package/dist/esm/constants/version.d.ts +1 -1
- package/dist/esm/constants/version.js +1 -1
- package/dist/esm/customHooks/analyticsLogger.js +1 -1
- package/dist/esm/customHooks/consoleLogger.js +34 -2
- package/dist/esm/customHooks/crashHandler.js +1 -1
- package/dist/esm/customHooks/networkLogger.js +184 -26
- package/dist/esm/helpers/searchQueryParser.d.ts +1 -1
- package/dist/esm/helpers/searchQueryParser.js +37 -291
- package/dist/esm/index.js +141 -27
- package/package.json +1 -1
- package/src/components/AnimatedEntrance.tsx +3 -3
- package/src/components/ConsoleLogCard.tsx +154 -103
- package/src/components/Inspector/ConsoleTab.tsx +27 -18
- package/src/components/Inspector/CrashTab.tsx +19 -5
- package/src/components/Inspector/DeviceInfoTab.tsx +224 -102
- package/src/components/Inspector/InspectorHeader.tsx +5 -3
- package/src/components/Inspector/MainScreen.tsx +2 -3
- package/src/components/Inspector/NetworkTab.tsx +1 -402
- package/src/components/Inspector/PerformanceTab.tsx +36 -7
- package/src/components/Inspector/ReduxTab.tsx +9 -1
- package/src/components/Inspector/StorageTab.tsx +27 -7
- package/src/components/JsonViewer.tsx +15 -2
- package/src/components/LogCard.tsx +528 -339
- package/src/constants/version.ts +1 -1
- package/src/customHooks/analyticsLogger.ts +1 -1
- package/src/customHooks/consoleLogger.ts +36 -3
- package/src/customHooks/crashHandler.ts +1 -1
- package/src/customHooks/networkLogger.ts +214 -26
- package/src/helpers/searchQueryParser.ts +40 -285
- package/src/index.tsx +332 -211
|
@@ -113,8 +113,8 @@ const MainScreen = () => {
|
|
|
113
113
|
visible={visible}
|
|
114
114
|
animationType={modalAnimationType}
|
|
115
115
|
transparent
|
|
116
|
-
statusBarTranslucent={true}
|
|
117
|
-
|
|
116
|
+
statusBarTranslucent={true}
|
|
117
|
+
onRequestClose={closeModal}>
|
|
118
118
|
<ErrorBoundary onClose={closeModal}>
|
|
119
119
|
<View style={styles.modalBackdrop}>
|
|
120
120
|
<Pressable
|
|
@@ -246,7 +246,6 @@ const MainScreen = () => {
|
|
|
246
246
|
</View>
|
|
247
247
|
</View>
|
|
248
248
|
</ErrorBoundary>
|
|
249
|
-
)}
|
|
250
249
|
{hasNavigationContext && (
|
|
251
250
|
<NavigationTracker onStateChange={setNavState} />
|
|
252
251
|
)}
|
|
@@ -227,94 +227,6 @@ const NetworkTab = React.memo(() => {
|
|
|
227
227
|
[quickCounts],
|
|
228
228
|
);
|
|
229
229
|
|
|
230
|
-
const SEARCH_SCOPES: Array<{
|
|
231
|
-
id: SearchScope;
|
|
232
|
-
label: string;
|
|
233
|
-
icon: (color: string) => React.JSX.Element;
|
|
234
|
-
}> = [
|
|
235
|
-
{
|
|
236
|
-
id: 'all',
|
|
237
|
-
label: 'All',
|
|
238
|
-
icon: color => <LayersIcon size={9.5} color={color} />,
|
|
239
|
-
},
|
|
240
|
-
{
|
|
241
|
-
id: 'url',
|
|
242
|
-
label: 'URL / Path',
|
|
243
|
-
icon: color => <GlobeIcon size={9.5} color={color} />,
|
|
244
|
-
},
|
|
245
|
-
{
|
|
246
|
-
id: 'reqBody',
|
|
247
|
-
label: 'Payload',
|
|
248
|
-
icon: color => <RequestIcon size={9.5} color={color} />,
|
|
249
|
-
},
|
|
250
|
-
{
|
|
251
|
-
id: 'resBody',
|
|
252
|
-
label: 'Response',
|
|
253
|
-
icon: color => <ResponseIcon size={9.5} color={color} />,
|
|
254
|
-
},
|
|
255
|
-
{
|
|
256
|
-
id: 'headers',
|
|
257
|
-
label: 'Headers',
|
|
258
|
-
icon: color => <HeadersIcon size={9.5} color={color} />,
|
|
259
|
-
},
|
|
260
|
-
];
|
|
261
|
-
|
|
262
|
-
const QUICK_API_QUERY_TAGS = useMemo(
|
|
263
|
-
() => [
|
|
264
|
-
{
|
|
265
|
-
label: 'Failed',
|
|
266
|
-
query: 'is:error',
|
|
267
|
-
icon: (color: string) => <CircleXIcon size={9.5} color={color} />,
|
|
268
|
-
},
|
|
269
|
-
{
|
|
270
|
-
label: 'Slow (>1s)',
|
|
271
|
-
query: 'slow:>1s',
|
|
272
|
-
icon: (color: string) => <ClockIcon size={9.5} color={color} />,
|
|
273
|
-
},
|
|
274
|
-
{
|
|
275
|
-
label: 'POST',
|
|
276
|
-
query: 'm:POST',
|
|
277
|
-
icon: (color: string) => <RequestIcon size={9.5} color={color} />,
|
|
278
|
-
},
|
|
279
|
-
{
|
|
280
|
-
label: 'GET',
|
|
281
|
-
query: 'm:GET',
|
|
282
|
-
icon: (color: string) => <ResponseIcon size={9.5} color={color} />,
|
|
283
|
-
},
|
|
284
|
-
{
|
|
285
|
-
label: 'GraphQL',
|
|
286
|
-
query: 'is:graphql',
|
|
287
|
-
icon: (color: string) => <AtomIcon size={9.5} color={color} />,
|
|
288
|
-
},
|
|
289
|
-
{
|
|
290
|
-
label: 'Axios',
|
|
291
|
-
query: 'client:axios',
|
|
292
|
-
icon: (color: string) => <BoltIcon size={9.5} color={color} />,
|
|
293
|
-
},
|
|
294
|
-
{
|
|
295
|
-
label: '200 OK',
|
|
296
|
-
query: 'status:200',
|
|
297
|
-
icon: (color: string) => <CircleCheckIcon size={9.5} color={color} />,
|
|
298
|
-
},
|
|
299
|
-
{
|
|
300
|
-
label: '404',
|
|
301
|
-
query: 'status:404',
|
|
302
|
-
icon: (color: string) => <CircleAlertIcon size={9.5} color={color} />,
|
|
303
|
-
},
|
|
304
|
-
{
|
|
305
|
-
label: '500',
|
|
306
|
-
query: 'status:500',
|
|
307
|
-
icon: (color: string) => <CircleXIcon size={9.5} color={color} />,
|
|
308
|
-
},
|
|
309
|
-
{
|
|
310
|
-
label: 'HTTPS',
|
|
311
|
-
query: 'is:https',
|
|
312
|
-
icon: (color: string) => <ShieldAlertIcon size={9.5} color={color} />,
|
|
313
|
-
},
|
|
314
|
-
],
|
|
315
|
-
[],
|
|
316
|
-
);
|
|
317
|
-
|
|
318
230
|
const networkMetrics = useMemo(() => {
|
|
319
231
|
if (!logs || logs.length === 0) return null;
|
|
320
232
|
let successCount = 0;
|
|
@@ -523,7 +435,7 @@ const NetworkTab = React.memo(() => {
|
|
|
523
435
|
size={15}
|
|
524
436
|
/>
|
|
525
437
|
<TextInput
|
|
526
|
-
placeholder="Search
|
|
438
|
+
placeholder="Search URL, status, method, headers, body..."
|
|
527
439
|
placeholderTextColor={AppColors.grayTextWeak}
|
|
528
440
|
value={search}
|
|
529
441
|
onChangeText={setSearch}
|
|
@@ -534,69 +446,6 @@ const NetworkTab = React.memo(() => {
|
|
|
534
446
|
autoCapitalize="none"
|
|
535
447
|
/>
|
|
536
448
|
|
|
537
|
-
{/* Match Case (Aa) & Regex (.*) Quick Toggles */}
|
|
538
|
-
<View
|
|
539
|
-
style={{
|
|
540
|
-
flexDirection: 'row',
|
|
541
|
-
alignItems: 'center',
|
|
542
|
-
gap: 3,
|
|
543
|
-
marginRight: 2,
|
|
544
|
-
}}>
|
|
545
|
-
<Pressable
|
|
546
|
-
hitSlop={8}
|
|
547
|
-
onPress={() => setIsCaseSensitive(prev => !prev)}
|
|
548
|
-
style={{
|
|
549
|
-
paddingHorizontal: 4.5,
|
|
550
|
-
paddingVertical: 2,
|
|
551
|
-
borderRadius: 4,
|
|
552
|
-
backgroundColor: isCaseSensitive
|
|
553
|
-
? AppColors.purple
|
|
554
|
-
: 'transparent',
|
|
555
|
-
borderWidth: 1,
|
|
556
|
-
borderColor: isCaseSensitive
|
|
557
|
-
? AppColors.purple
|
|
558
|
-
: `${AppColors.grayBorderSecondary}`,
|
|
559
|
-
}}>
|
|
560
|
-
<Text
|
|
561
|
-
style={{
|
|
562
|
-
fontFamily: AppFonts.interBold,
|
|
563
|
-
fontSize: 9.5,
|
|
564
|
-
color: isCaseSensitive
|
|
565
|
-
? AppColors.white
|
|
566
|
-
: AppColors.grayTextWeak,
|
|
567
|
-
}}>
|
|
568
|
-
Aa
|
|
569
|
-
</Text>
|
|
570
|
-
</Pressable>
|
|
571
|
-
|
|
572
|
-
<Pressable
|
|
573
|
-
hitSlop={8}
|
|
574
|
-
onPress={() => setIsRegexSearch(prev => !prev)}
|
|
575
|
-
style={{
|
|
576
|
-
paddingHorizontal: 4.5,
|
|
577
|
-
paddingVertical: 2,
|
|
578
|
-
borderRadius: 4,
|
|
579
|
-
backgroundColor: isRegexSearch
|
|
580
|
-
? AppColors.purple
|
|
581
|
-
: 'transparent',
|
|
582
|
-
borderWidth: 1,
|
|
583
|
-
borderColor: isRegexSearch
|
|
584
|
-
? AppColors.purple
|
|
585
|
-
: `${AppColors.grayBorderSecondary}`,
|
|
586
|
-
}}>
|
|
587
|
-
<Text
|
|
588
|
-
style={{
|
|
589
|
-
fontFamily: AppFonts.interBold,
|
|
590
|
-
fontSize: 9.5,
|
|
591
|
-
color: isRegexSearch
|
|
592
|
-
? AppColors.white
|
|
593
|
-
: AppColors.grayTextWeak,
|
|
594
|
-
}}>
|
|
595
|
-
.*
|
|
596
|
-
</Text>
|
|
597
|
-
</Pressable>
|
|
598
|
-
</View>
|
|
599
|
-
|
|
600
449
|
{search.length > 0 && (
|
|
601
450
|
<View
|
|
602
451
|
style={{
|
|
@@ -721,113 +570,6 @@ const NetworkTab = React.memo(() => {
|
|
|
721
570
|
</View>
|
|
722
571
|
</View>
|
|
723
572
|
|
|
724
|
-
{/* Quick Search Scope & Filter Tags Row */}
|
|
725
|
-
<View style={{paddingBottom: 4}}>
|
|
726
|
-
<ScrollView
|
|
727
|
-
horizontal
|
|
728
|
-
showsHorizontalScrollIndicator={false}
|
|
729
|
-
contentContainerStyle={{
|
|
730
|
-
paddingHorizontal: 12,
|
|
731
|
-
flexDirection: 'row',
|
|
732
|
-
alignItems: 'center',
|
|
733
|
-
gap: 5,
|
|
734
|
-
paddingVertical: 2,
|
|
735
|
-
}}>
|
|
736
|
-
{/* Search Scopes */}
|
|
737
|
-
{SEARCH_SCOPES.map(s => {
|
|
738
|
-
const isActive = searchScope === s.id;
|
|
739
|
-
return (
|
|
740
|
-
<TouchableScale
|
|
741
|
-
key={`scope_${s.id}`}
|
|
742
|
-
onPress={() => setSearchScope(s.id)}
|
|
743
|
-
hitSlop={6}
|
|
744
|
-
style={{
|
|
745
|
-
flexDirection: 'row',
|
|
746
|
-
alignItems: 'center',
|
|
747
|
-
gap: 3.5,
|
|
748
|
-
paddingHorizontal: 7.5,
|
|
749
|
-
paddingVertical: 3.5,
|
|
750
|
-
borderRadius: 6,
|
|
751
|
-
backgroundColor: isActive
|
|
752
|
-
? AppColors.purple
|
|
753
|
-
: AppColors.grayBackground,
|
|
754
|
-
borderWidth: 1,
|
|
755
|
-
borderColor: isActive
|
|
756
|
-
? AppColors.purple
|
|
757
|
-
: AppColors.grayBorderSecondary,
|
|
758
|
-
}}>
|
|
759
|
-
{s.icon(isActive ? AppColors.white : AppColors.grayTextWeak)}
|
|
760
|
-
<Text
|
|
761
|
-
style={{
|
|
762
|
-
fontFamily: AppFonts.interBold,
|
|
763
|
-
fontSize: 10,
|
|
764
|
-
color: isActive ? AppColors.white : AppColors.grayText,
|
|
765
|
-
}}>
|
|
766
|
-
{s.label}
|
|
767
|
-
</Text>
|
|
768
|
-
</TouchableScale>
|
|
769
|
-
);
|
|
770
|
-
})}
|
|
771
|
-
|
|
772
|
-
<View
|
|
773
|
-
style={{
|
|
774
|
-
width: 1,
|
|
775
|
-
height: 14,
|
|
776
|
-
backgroundColor: AppColors.dividerColor,
|
|
777
|
-
marginHorizontal: 3,
|
|
778
|
-
}}
|
|
779
|
-
/>
|
|
780
|
-
|
|
781
|
-
{/* Quick Query Suggestions */}
|
|
782
|
-
{QUICK_API_QUERY_TAGS.map(q => {
|
|
783
|
-
const isActive = search.includes(q.query);
|
|
784
|
-
return (
|
|
785
|
-
<TouchableScale
|
|
786
|
-
key={`quick_${q.query}`}
|
|
787
|
-
onPress={() => {
|
|
788
|
-
setSearch(prev => {
|
|
789
|
-
if (prev.includes(q.query)) {
|
|
790
|
-
return prev
|
|
791
|
-
.replace(q.query, '')
|
|
792
|
-
.replace(/\s+/g, ' ')
|
|
793
|
-
.trim();
|
|
794
|
-
}
|
|
795
|
-
return `${prev} ${q.query}`.trim();
|
|
796
|
-
});
|
|
797
|
-
}}
|
|
798
|
-
hitSlop={6}
|
|
799
|
-
style={{
|
|
800
|
-
flexDirection: 'row',
|
|
801
|
-
alignItems: 'center',
|
|
802
|
-
gap: 3.5,
|
|
803
|
-
paddingHorizontal: 7.5,
|
|
804
|
-
paddingVertical: 3.5,
|
|
805
|
-
borderRadius: 6,
|
|
806
|
-
backgroundColor: isActive
|
|
807
|
-
? `${AppColors.purple}20`
|
|
808
|
-
: AppColors.grayBackground,
|
|
809
|
-
borderWidth: 1,
|
|
810
|
-
borderColor: isActive
|
|
811
|
-
? AppColors.purple
|
|
812
|
-
: AppColors.grayBorderSecondary,
|
|
813
|
-
}}>
|
|
814
|
-
{q.icon(isActive ? AppColors.purple : AppColors.grayTextWeak)}
|
|
815
|
-
<Text
|
|
816
|
-
style={{
|
|
817
|
-
fontFamily: AppFonts.interMedium,
|
|
818
|
-
fontSize: 10,
|
|
819
|
-
color: isActive
|
|
820
|
-
? AppColors.purple
|
|
821
|
-
: AppColors.grayText,
|
|
822
|
-
}}>
|
|
823
|
-
{q.label}
|
|
824
|
-
</Text>
|
|
825
|
-
</TouchableScale>
|
|
826
|
-
);
|
|
827
|
-
})}
|
|
828
|
-
</ScrollView>
|
|
829
|
-
</View>
|
|
830
|
-
|
|
831
573
|
{/* Quick Filter Horizontal Chips Bar with Live Counts */}
|
|
832
574
|
<View style={{marginBottom: 8}}>
|
|
833
575
|
<ScrollView
|
|
@@ -967,138 +709,6 @@ const NetworkTab = React.memo(() => {
|
|
|
967
709
|
</ScrollView>
|
|
968
710
|
</View>
|
|
969
711
|
|
|
970
|
-
{/* Search Scope Selector Bar (Visible on search or focus) */}
|
|
971
|
-
{(isSearchFocused || search.length > 0) && (
|
|
972
|
-
<View
|
|
973
|
-
style={{
|
|
974
|
-
flexDirection: 'row',
|
|
975
|
-
alignItems: 'center',
|
|
976
|
-
paddingHorizontal: 12,
|
|
977
|
-
marginBottom: 6,
|
|
978
|
-
gap: 6,
|
|
979
|
-
}}>
|
|
980
|
-
<Text
|
|
981
|
-
style={{
|
|
982
|
-
fontFamily: AppFonts.interBold,
|
|
983
|
-
fontSize: 9.5,
|
|
984
|
-
color: AppColors.grayTextWeak,
|
|
985
|
-
textTransform: 'uppercase',
|
|
986
|
-
letterSpacing: 0.5,
|
|
987
|
-
}}>
|
|
988
|
-
Scope:
|
|
989
|
-
</Text>
|
|
990
|
-
<ScrollView
|
|
991
|
-
horizontal
|
|
992
|
-
showsHorizontalScrollIndicator={false}
|
|
993
|
-
contentContainerStyle={{
|
|
994
|
-
flexDirection: 'row',
|
|
995
|
-
alignItems: 'center',
|
|
996
|
-
gap: 5,
|
|
997
|
-
}}>
|
|
998
|
-
{SEARCH_SCOPES.map(s => {
|
|
999
|
-
const isSelected = searchScope === s.id;
|
|
1000
|
-
const iconColor = isSelected ? AppColors.white : AppColors.grayText;
|
|
1001
|
-
return (
|
|
1002
|
-
<TouchableScale
|
|
1003
|
-
key={s.id}
|
|
1004
|
-
onPress={() => setSearchScope(s.id)}>
|
|
1005
|
-
<View
|
|
1006
|
-
style={{
|
|
1007
|
-
flexDirection: 'row',
|
|
1008
|
-
alignItems: 'center',
|
|
1009
|
-
gap: 4,
|
|
1010
|
-
paddingHorizontal: 7,
|
|
1011
|
-
paddingVertical: 2.5,
|
|
1012
|
-
borderRadius: 5,
|
|
1013
|
-
backgroundColor: isSelected
|
|
1014
|
-
? AppColors.purple
|
|
1015
|
-
: `${AppColors.grayBorderSecondary}40`,
|
|
1016
|
-
borderWidth: 1,
|
|
1017
|
-
borderColor: isSelected
|
|
1018
|
-
? AppColors.purple
|
|
1019
|
-
: AppColors.grayBorderSecondary,
|
|
1020
|
-
}}>
|
|
1021
|
-
{s.icon(iconColor)}
|
|
1022
|
-
<Text
|
|
1023
|
-
style={{
|
|
1024
|
-
fontFamily: AppFonts.interBold,
|
|
1025
|
-
fontSize: 9.5,
|
|
1026
|
-
color: isSelected
|
|
1027
|
-
? AppColors.white
|
|
1028
|
-
: AppColors.grayText,
|
|
1029
|
-
}}>
|
|
1030
|
-
{s.label}
|
|
1031
|
-
</Text>
|
|
1032
|
-
</View>
|
|
1033
|
-
</TouchableScale>
|
|
1034
|
-
);
|
|
1035
|
-
})}
|
|
1036
|
-
</ScrollView>
|
|
1037
|
-
</View>
|
|
1038
|
-
)}
|
|
1039
|
-
|
|
1040
|
-
{/* Advanced Search Quick Query Suggestions Bar */}
|
|
1041
|
-
{(isSearchFocused || search.length > 0) && (
|
|
1042
|
-
<ScrollView
|
|
1043
|
-
horizontal
|
|
1044
|
-
showsHorizontalScrollIndicator={false}
|
|
1045
|
-
style={{marginBottom: 8, maxHeight: 28}}
|
|
1046
|
-
contentContainerStyle={{
|
|
1047
|
-
paddingHorizontal: 12,
|
|
1048
|
-
flexDirection: 'row',
|
|
1049
|
-
alignItems: 'center',
|
|
1050
|
-
gap: 5,
|
|
1051
|
-
}}>
|
|
1052
|
-
{QUICK_API_QUERY_TAGS.map(item => {
|
|
1053
|
-
const isSelected = search.includes(item.query);
|
|
1054
|
-
return (
|
|
1055
|
-
<TouchableScale
|
|
1056
|
-
key={item.query}
|
|
1057
|
-
onPress={() => {
|
|
1058
|
-
if (isSelected) {
|
|
1059
|
-
setSearch(prev =>
|
|
1060
|
-
prev.replace(item.query, '').trim(),
|
|
1061
|
-
);
|
|
1062
|
-
} else {
|
|
1063
|
-
setSearch(prev =>
|
|
1064
|
-
prev ? `${prev} ${item.query}`.trim() : item.query,
|
|
1065
|
-
);
|
|
1066
|
-
}
|
|
1067
|
-
}}>
|
|
1068
|
-
<View
|
|
1069
|
-
style={{
|
|
1070
|
-
flexDirection: 'row',
|
|
1071
|
-
alignItems: 'center',
|
|
1072
|
-
gap: 4,
|
|
1073
|
-
paddingHorizontal: 7,
|
|
1074
|
-
paddingVertical: 2.5,
|
|
1075
|
-
borderRadius: 5,
|
|
1076
|
-
backgroundColor: isSelected
|
|
1077
|
-
? AppColors.purple
|
|
1078
|
-
: `${AppColors.purple}14`,
|
|
1079
|
-
borderWidth: 1,
|
|
1080
|
-
borderColor: isSelected
|
|
1081
|
-
? AppColors.purple
|
|
1082
|
-
: `${AppColors.purple}30`,
|
|
1083
|
-
}}>
|
|
1084
|
-
{item.icon(isSelected ? AppColors.white : AppColors.purple)}
|
|
1085
|
-
<Text
|
|
1086
|
-
style={{
|
|
1087
|
-
fontFamily: AppFonts.interBold,
|
|
1088
|
-
fontSize: 9.5,
|
|
1089
|
-
color: isSelected
|
|
1090
|
-
? AppColors.white
|
|
1091
|
-
: AppColors.purple,
|
|
1092
|
-
}}>
|
|
1093
|
-
{item.label}
|
|
1094
|
-
</Text>
|
|
1095
|
-
</View>
|
|
1096
|
-
</TouchableScale>
|
|
1097
|
-
);
|
|
1098
|
-
})}
|
|
1099
|
-
</ScrollView>
|
|
1100
|
-
)}
|
|
1101
|
-
|
|
1102
712
|
{/* Active Filter Helper Status Bar */}
|
|
1103
713
|
{(quickFilter !== 'all' ||
|
|
1104
714
|
search.trim().length > 0 ||
|
|
@@ -1145,17 +755,6 @@ const NetworkTab = React.memo(() => {
|
|
|
1145
755
|
</TouchableScale>
|
|
1146
756
|
</View>
|
|
1147
757
|
)}
|
|
1148
|
-
|
|
1149
|
-
{(search ||
|
|
1150
|
-
statusFilters.size > 0 ||
|
|
1151
|
-
methodFilters.size > 0 ||
|
|
1152
|
-
quickFilter !== 'all') && (
|
|
1153
|
-
<Text style={styles.resultCount}>
|
|
1154
|
-
{filteredLogs.length === logs.length
|
|
1155
|
-
? `${logs.length} requests`
|
|
1156
|
-
: `${filteredLogs.length} of ${logs.length} filtered requests`}
|
|
1157
|
-
</Text>
|
|
1158
|
-
)}
|
|
1159
758
|
</View>
|
|
1160
759
|
}
|
|
1161
760
|
ListEmptyComponent={
|
|
@@ -248,11 +248,19 @@ const PerformanceTab = React.memo(() => {
|
|
|
248
248
|
// Filtered Events
|
|
249
249
|
const filteredEvents = useMemo(() => {
|
|
250
250
|
return events.filter(e => {
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
251
|
+
let matchSearch = true;
|
|
252
|
+
if (search && search.trim().length > 0) {
|
|
253
|
+
const queryTokens = search.trim().toLowerCase().split(/\s+/).filter(Boolean);
|
|
254
|
+
const corpus = [
|
|
255
|
+
e.label || '',
|
|
256
|
+
e.detail || '',
|
|
257
|
+
e.source || '',
|
|
258
|
+
e.category || '',
|
|
259
|
+
e.severity || '',
|
|
260
|
+
e.bottleneckThread || '',
|
|
261
|
+
].join(' ').toLowerCase();
|
|
262
|
+
matchSearch = queryTokens.every(tok => corpus.includes(tok));
|
|
263
|
+
}
|
|
256
264
|
|
|
257
265
|
const matchFilter =
|
|
258
266
|
filterCategory === 'ALL'
|
|
@@ -1052,10 +1060,31 @@ const PerformanceTab = React.memo(() => {
|
|
|
1052
1060
|
{filteredEvents.length === 0 ? (
|
|
1053
1061
|
<View style={perfStyles.emptyCard}>
|
|
1054
1062
|
<BoltIcon color={AppColors.amber500} size={30} />
|
|
1055
|
-
<Text style={perfStyles.emptyTitle}>
|
|
1063
|
+
<Text style={perfStyles.emptyTitle}>
|
|
1064
|
+
{search.trim().length > 0 ? 'No Matching Events' : t('performance.emptyTitle')}
|
|
1065
|
+
</Text>
|
|
1056
1066
|
<Text style={perfStyles.emptySub}>
|
|
1057
|
-
{
|
|
1067
|
+
{search.trim().length > 0
|
|
1068
|
+
? `No performance events match "${search}"`
|
|
1069
|
+
: t('performance.emptySubtitle')}
|
|
1058
1070
|
</Text>
|
|
1071
|
+
{search.trim().length > 0 && (
|
|
1072
|
+
<TouchableScale
|
|
1073
|
+
onPress={() => setSearch('')}
|
|
1074
|
+
style={{
|
|
1075
|
+
marginTop: 10,
|
|
1076
|
+
paddingHorizontal: 14,
|
|
1077
|
+
paddingVertical: 6,
|
|
1078
|
+
borderRadius: 8,
|
|
1079
|
+
backgroundColor: AppColors.grayBackground,
|
|
1080
|
+
borderWidth: 1,
|
|
1081
|
+
borderColor: AppColors.grayBorderSecondary,
|
|
1082
|
+
}}>
|
|
1083
|
+
<Text style={{color: AppColors.brandPurple, fontSize: 12, fontFamily: AppFonts.interBold}}>
|
|
1084
|
+
Clear Search
|
|
1085
|
+
</Text>
|
|
1086
|
+
</TouchableScale>
|
|
1087
|
+
)}
|
|
1059
1088
|
</View>
|
|
1060
1089
|
) : (
|
|
1061
1090
|
filteredEvents.map(event => {
|
|
@@ -670,7 +670,15 @@ const ReduxTab = React.memo(() => {
|
|
|
670
670
|
renderToHardwareTextureAndroid={true}
|
|
671
671
|
ListEmptyComponent={
|
|
672
672
|
<EmptyState
|
|
673
|
-
isSearch={reduxSearch.length > 0}
|
|
673
|
+
isSearch={reduxSearch.trim().length > 0}
|
|
674
|
+
searchQuery={reduxSearch}
|
|
675
|
+
onClearSearch={() => setReduxSearch('')}
|
|
676
|
+
customTitle={reduxSearch.trim().length > 0 ? 'No Matching Slices' : 'No Redux State Detected'}
|
|
677
|
+
customSub={
|
|
678
|
+
reduxSearch.trim().length > 0
|
|
679
|
+
? `No Redux slices match "${reduxSearch}"`
|
|
680
|
+
: 'Attach the Redux store or dispatch actions to see state slices.'
|
|
681
|
+
}
|
|
674
682
|
/>
|
|
675
683
|
}
|
|
676
684
|
ListFooterComponent={
|
|
@@ -356,10 +356,11 @@ export const StorageTab = React.memo(() => {
|
|
|
356
356
|
// Filter entries
|
|
357
357
|
const filteredEntries = useMemo(() => {
|
|
358
358
|
if (!search.trim()) return entries;
|
|
359
|
-
const
|
|
360
|
-
return entries.filter(
|
|
361
|
-
|
|
362
|
-
|
|
359
|
+
const tokens = search.toLowerCase().trim().split(/\s+/).filter(Boolean);
|
|
360
|
+
return entries.filter(e => {
|
|
361
|
+
const corpus = `${e.key} ${e.value}`.toLowerCase();
|
|
362
|
+
return tokens.every(tok => corpus.includes(tok));
|
|
363
|
+
});
|
|
363
364
|
}, [entries, search]);
|
|
364
365
|
|
|
365
366
|
const totalBytes = useMemo(() => {
|
|
@@ -585,13 +586,32 @@ export const StorageTab = React.memo(() => {
|
|
|
585
586
|
<DatabaseIcon size={28} color={AppColors.grayTextWeak} />
|
|
586
587
|
</View>
|
|
587
588
|
<Text style={styles.emptyTitle}>
|
|
588
|
-
{search
|
|
589
|
+
{search.trim().length > 0
|
|
590
|
+
? 'No matching keys found'
|
|
591
|
+
: `No ${activeDriver === 'asyncStorage' ? 'AsyncStorage' : 'MMKV'} Keys`}
|
|
589
592
|
</Text>
|
|
590
593
|
<Text style={styles.emptySubtitle}>
|
|
591
|
-
{search
|
|
592
|
-
?
|
|
594
|
+
{search.trim().length > 0
|
|
595
|
+
? `No keys or values match "${search}"`
|
|
593
596
|
: `Storage is auto-detected. Tap "+ Add" above to create your first ${activeDriver === 'asyncStorage' ? 'AsyncStorage' : 'MMKV'} key!`}
|
|
594
597
|
</Text>
|
|
598
|
+
{search.trim().length > 0 && (
|
|
599
|
+
<TouchableScale
|
|
600
|
+
onPress={() => setSearch('')}
|
|
601
|
+
style={{
|
|
602
|
+
marginTop: 12,
|
|
603
|
+
paddingHorizontal: 14,
|
|
604
|
+
paddingVertical: 6,
|
|
605
|
+
borderRadius: 8,
|
|
606
|
+
backgroundColor: AppColors.grayBackground,
|
|
607
|
+
borderWidth: 1,
|
|
608
|
+
borderColor: AppColors.grayBorderSecondary,
|
|
609
|
+
}}>
|
|
610
|
+
<Text style={{color: AppColors.brandPurple, fontSize: 12, fontFamily: AppFonts.interBold}}>
|
|
611
|
+
Clear Search
|
|
612
|
+
</Text>
|
|
613
|
+
</TouchableScale>
|
|
614
|
+
)}
|
|
595
615
|
</View>
|
|
596
616
|
}
|
|
597
617
|
ListFooterComponent={<View style={{height: 60}} />}
|
|
@@ -186,11 +186,24 @@ const JsonViewer = React.memo(({
|
|
|
186
186
|
);
|
|
187
187
|
}
|
|
188
188
|
|
|
189
|
-
|
|
189
|
+
let keys = Object.keys(data as object);
|
|
190
|
+
if (search && search.trim().length > 0) {
|
|
191
|
+
const q = search.trim().toLowerCase();
|
|
192
|
+
keys = keys.filter(key => {
|
|
193
|
+
const val = (data as any)[key];
|
|
194
|
+
const valStr = typeof val === 'object' && val !== null ? JSON.stringify(val) : String(val);
|
|
195
|
+
return key.toLowerCase().includes(q) || valStr.toLowerCase().includes(q);
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
|
|
190
199
|
if (keys.length === 0) {
|
|
191
200
|
return (
|
|
192
201
|
<View style={localStyles.emptyTable}>
|
|
193
|
-
<Text style={localStyles.emptyTableText}>
|
|
202
|
+
<Text style={localStyles.emptyTableText}>
|
|
203
|
+
{search && search.trim().length > 0
|
|
204
|
+
? 'No matching keys or values found'
|
|
205
|
+
: t('network.jsonViewer.emptyTable')}
|
|
206
|
+
</Text>
|
|
194
207
|
</View>
|
|
195
208
|
);
|
|
196
209
|
}
|