react-native-inapp-inspector 2.2.9 → 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.
Files changed (92) hide show
  1. package/dist/commonjs/components/AppHeaderLogo.js +45 -12
  2. package/dist/commonjs/components/BrandSquareIcon.js +92 -49
  3. package/dist/commonjs/components/EmptyState.d.ts +7 -2
  4. package/dist/commonjs/components/EmptyState.js +11 -5
  5. package/dist/commonjs/components/Inspector/AnalyticsTab.js +29 -18
  6. package/dist/commonjs/components/Inspector/ConsoleTab.js +6 -1
  7. package/dist/commonjs/components/Inspector/CrashDetail.js +43 -9
  8. package/dist/commonjs/components/Inspector/CrashTab.js +34 -3
  9. package/dist/commonjs/components/Inspector/DeviceInfoTab.js +80 -16
  10. package/dist/commonjs/components/Inspector/InspectorHeader.js +16 -3
  11. package/dist/commonjs/components/Inspector/NetworkDetail.js +3 -2
  12. package/dist/commonjs/components/Inspector/NetworkTab.js +103 -4
  13. package/dist/commonjs/components/Inspector/ReduxTab.js +19 -3
  14. package/dist/commonjs/components/Inspector/SettingsPanel.js +4 -4
  15. package/dist/commonjs/components/Inspector/StorageTab.js +19 -3
  16. package/dist/commonjs/components/JsonViewer.js +2 -0
  17. package/dist/commonjs/components/MetaAccordion.js +15 -3
  18. package/dist/commonjs/constants/version.d.ts +1 -1
  19. package/dist/commonjs/constants/version.js +1 -1
  20. package/dist/commonjs/customHooks/networkLogger.d.ts +3 -0
  21. package/dist/commonjs/customHooks/networkLogger.js +10 -1
  22. package/dist/commonjs/helpers/index.d.ts +6 -0
  23. package/dist/commonjs/helpers/index.js +196 -6
  24. package/dist/commonjs/helpers/searchQueryParser.js +62 -20
  25. package/dist/commonjs/i18n/index.d.ts +13 -0
  26. package/dist/commonjs/i18n/index.js +35 -2
  27. package/dist/commonjs/index.d.ts +3 -0
  28. package/dist/commonjs/index.js +80 -11
  29. package/dist/commonjs/styles/AppColors.d.ts +4 -0
  30. package/dist/commonjs/styles/AppColors.js +11 -1
  31. package/dist/commonjs/styles/AppFonts.d.ts +11 -0
  32. package/dist/commonjs/styles/AppFonts.js +11 -1
  33. package/dist/commonjs/types/interfaces.d.ts +1 -0
  34. package/dist/esm/components/AppHeaderLogo.js +45 -12
  35. package/dist/esm/components/BrandSquareIcon.js +92 -49
  36. package/dist/esm/components/EmptyState.d.ts +7 -2
  37. package/dist/esm/components/EmptyState.js +11 -5
  38. package/dist/esm/components/Inspector/AnalyticsTab.js +30 -19
  39. package/dist/esm/components/Inspector/ConsoleTab.js +6 -1
  40. package/dist/esm/components/Inspector/CrashDetail.js +43 -9
  41. package/dist/esm/components/Inspector/CrashTab.js +34 -3
  42. package/dist/esm/components/Inspector/DeviceInfoTab.js +80 -16
  43. package/dist/esm/components/Inspector/InspectorHeader.js +17 -4
  44. package/dist/esm/components/Inspector/NetworkDetail.js +3 -2
  45. package/dist/esm/components/Inspector/NetworkTab.js +103 -4
  46. package/dist/esm/components/Inspector/ReduxTab.js +19 -3
  47. package/dist/esm/components/Inspector/SettingsPanel.js +4 -4
  48. package/dist/esm/components/Inspector/StorageTab.js +19 -3
  49. package/dist/esm/components/JsonViewer.js +2 -0
  50. package/dist/esm/components/MetaAccordion.js +15 -3
  51. package/dist/esm/constants/version.d.ts +1 -1
  52. package/dist/esm/constants/version.js +1 -1
  53. package/dist/esm/customHooks/networkLogger.d.ts +3 -0
  54. package/dist/esm/customHooks/networkLogger.js +8 -0
  55. package/dist/esm/helpers/index.d.ts +6 -0
  56. package/dist/esm/helpers/index.js +193 -5
  57. package/dist/esm/helpers/searchQueryParser.js +62 -20
  58. package/dist/esm/i18n/index.d.ts +13 -0
  59. package/dist/esm/i18n/index.js +33 -3
  60. package/dist/esm/index.d.ts +3 -0
  61. package/dist/esm/index.js +68 -12
  62. package/dist/esm/styles/AppColors.d.ts +4 -0
  63. package/dist/esm/styles/AppColors.js +9 -0
  64. package/dist/esm/styles/AppFonts.d.ts +11 -0
  65. package/dist/esm/styles/AppFonts.js +9 -0
  66. package/dist/esm/types/interfaces.d.ts +1 -0
  67. package/package.json +1 -1
  68. package/src/components/AppHeaderLogo.tsx +46 -12
  69. package/src/components/BrandSquareIcon.tsx +127 -78
  70. package/src/components/EmptyState.tsx +27 -5
  71. package/src/components/Inspector/AnalyticsTab.tsx +48 -27
  72. package/src/components/Inspector/ConsoleTab.tsx +10 -0
  73. package/src/components/Inspector/CrashDetail.tsx +65 -9
  74. package/src/components/Inspector/CrashTab.tsx +41 -3
  75. package/src/components/Inspector/DeviceInfoTab.tsx +87 -16
  76. package/src/components/Inspector/InspectorHeader.tsx +24 -4
  77. package/src/components/Inspector/NetworkDetail.tsx +4 -4
  78. package/src/components/Inspector/NetworkTab.tsx +129 -4
  79. package/src/components/Inspector/ReduxTab.tsx +26 -8
  80. package/src/components/Inspector/SettingsPanel.tsx +4 -4
  81. package/src/components/Inspector/StorageTab.tsx +21 -3
  82. package/src/components/JsonViewer.tsx +2 -0
  83. package/src/components/MetaAccordion.tsx +18 -3
  84. package/src/constants/version.ts +1 -1
  85. package/src/customHooks/networkLogger.ts +15 -0
  86. package/src/helpers/index.ts +213 -5
  87. package/src/helpers/searchQueryParser.ts +63 -20
  88. package/src/i18n/index.ts +38 -3
  89. package/src/index.tsx +89 -11
  90. package/src/styles/AppColors.ts +9 -0
  91. package/src/styles/AppFonts.ts +16 -0
  92. package/src/types/interfaces.ts +1 -0
@@ -11,6 +11,7 @@ import {animateNextLayout, useInspector} from './InspectorContext';
11
11
  import AnalyticsEventCard from '../AnalyticsEventCard';
12
12
  import AnalyticsFilterModal from './AnalyticsFilterModal';
13
13
  import EndOfListFooter from '../EndOfListFooter';
14
+ import EmptyState from '../EmptyState';
14
15
  import styles from '../../styles';
15
16
  import {AppColors} from '../../styles/AppColors';
16
17
  import {AppFonts} from '../../styles/AppFonts';
@@ -1183,15 +1184,38 @@ const AnalyticsTab = React.memo(() => {
1183
1184
  autoCapitalize="none"
1184
1185
  />
1185
1186
  {analyticsSearch.length > 0 && (
1186
- <Pressable
1187
- onPress={() => setAnalyticsSearch('')}
1188
- hitSlop={10}
1189
- style={styles.clearBtn}>
1190
- <ClearIcon
1191
- color={AppColors.grayTextWeak}
1192
- size={14}
1193
- />
1194
- </Pressable>
1187
+ <View
1188
+ style={{
1189
+ flexDirection: 'row',
1190
+ alignItems: 'center',
1191
+ gap: 4,
1192
+ }}>
1193
+ <View
1194
+ style={{
1195
+ backgroundColor: `${AppColors.purple}20`,
1196
+ borderRadius: 10,
1197
+ paddingHorizontal: 6,
1198
+ paddingVertical: 1.5,
1199
+ }}>
1200
+ <Text
1201
+ style={{
1202
+ color: AppColors.purple,
1203
+ fontSize: 9.5,
1204
+ fontFamily: AppFonts.interBold,
1205
+ }}>
1206
+ {filteredAnalyticsEvents.length}
1207
+ </Text>
1208
+ </View>
1209
+ <Pressable
1210
+ onPress={() => setAnalyticsSearch('')}
1211
+ hitSlop={10}
1212
+ style={styles.clearBtn}>
1213
+ <ClearIcon
1214
+ color={AppColors.grayTextWeak}
1215
+ size={13}
1216
+ />
1217
+ </Pressable>
1218
+ </View>
1195
1219
  )}
1196
1220
  </View>
1197
1221
  <View style={styles.toolbarRight}>
@@ -1292,24 +1316,21 @@ const AnalyticsTab = React.memo(() => {
1292
1316
  removeClippedSubviews={true}
1293
1317
  renderToHardwareTextureAndroid={true}
1294
1318
  ListEmptyComponent={
1295
- <View style={styles.emptyContainer}>
1296
- <View style={styles.emptyIconWrap}>
1297
- <EmptyRadarIcon
1298
- color={AppColors.purple}
1299
- size={32}
1300
- />
1301
- </View>
1302
- <Text style={styles.emptyTitle}>
1303
- {analyticsSearch.length > 0
1304
- ? 'No matching events'
1305
- : 'No analytics events yet'}
1306
- </Text>
1307
- <Text style={styles.emptySub}>
1308
- {analyticsSearch.length > 0
1309
- ? 'Try adjusting your search.'
1310
- : 'Call setupAnalyticsLogger(analytics()) at app start.'}
1311
- </Text>
1312
- </View>
1319
+ <EmptyState
1320
+ isSearch={analyticsSearch.length > 0}
1321
+ searchQuery={analyticsSearch}
1322
+ customTitle={
1323
+ analyticsSearch.length > 0
1324
+ ? 'No matching analytics events'
1325
+ : 'No analytics events yet'
1326
+ }
1327
+ customSub={
1328
+ analyticsSearch.length > 0
1329
+ ? `No events matched "${analyticsSearch}"`
1330
+ : 'Call setupAnalyticsLogger(analytics()) at app start.'
1331
+ }
1332
+ onClearSearch={() => setAnalyticsSearch('')}
1333
+ />
1313
1334
  }
1314
1335
  ListFooterComponent={
1315
1336
  filteredAnalyticsEvents.length > 0 ? (
@@ -682,6 +682,16 @@ const ConsoleTab = React.memo(() => {
682
682
  isSearch={
683
683
  logSearch.length > 0 || logFilters.size > 0
684
684
  }
685
+ searchQuery={logSearch}
686
+ customTitle={
687
+ logSearch.length > 0
688
+ ? 'No matching console logs'
689
+ : 'No console logs'
690
+ }
691
+ onClearSearch={() => {
692
+ setLogSearch('');
693
+ setLogFilters(new Set());
694
+ }}
685
695
  />
686
696
  }
687
697
  ListFooterComponent={
@@ -13,6 +13,7 @@ import TouchableScale from '../TouchableScale';
13
13
  import SegmentedTabs from '../SegmentedTabs';
14
14
  import HighlightText from '../HighlightText';
15
15
  import JsonViewer from '../JsonViewer';
16
+ import CopyButton from '../CopyButton';
16
17
  import {AppColors} from '../../styles/AppColors';
17
18
  import {AppFonts} from '../../styles/AppFonts';
18
19
  import {
@@ -485,9 +486,27 @@ const CrashDetail: React.FC = React.memo(() => {
485
486
  <View style={{gap: 12}}>
486
487
  {/* Device & OS Diagnostics Card */}
487
488
  <View style={localStyles.sectionCard}>
488
- <View style={localStyles.sectionCardHeader}>
489
- <GlobeIcon color={AppColors.purple} size={14} />
490
- <Text style={localStyles.sectionCardTitle}>{t('crash.deviceEnvironment')}</Text>
489
+ <View
490
+ style={[
491
+ localStyles.sectionCardHeader,
492
+ {justifyContent: 'space-between'},
493
+ ]}>
494
+ <View
495
+ style={{flexDirection: 'row', alignItems: 'center', gap: 6}}>
496
+ <GlobeIcon color={AppColors.purple} size={14} />
497
+ <Text style={localStyles.sectionCardTitle}>
498
+ {t('crash.deviceEnvironment')}
499
+ </Text>
500
+ </View>
501
+ <CopyButton
502
+ value={
503
+ selectedCrash.deviceInfo || {
504
+ platform: Platform.OS,
505
+ osVersion: String(Platform.Version),
506
+ }
507
+ }
508
+ label="Diagnostics"
509
+ />
491
510
  </View>
492
511
 
493
512
  <View style={localStyles.diagGrid}>
@@ -538,9 +557,22 @@ const CrashDetail: React.FC = React.memo(() => {
538
557
  {/* Memory Metrics Card */}
539
558
  {selectedCrash.memoryInfo && (
540
559
  <View style={localStyles.sectionCard}>
541
- <View style={localStyles.sectionCardHeader}>
542
- <LayersIcon color={AppColors.purple} size={14} />
543
- <Text style={localStyles.sectionCardTitle}>{t('crash.jsHeapMemory')}</Text>
560
+ <View
561
+ style={[
562
+ localStyles.sectionCardHeader,
563
+ {justifyContent: 'space-between'},
564
+ ]}>
565
+ <View
566
+ style={{flexDirection: 'row', alignItems: 'center', gap: 6}}>
567
+ <LayersIcon color={AppColors.purple} size={14} />
568
+ <Text style={localStyles.sectionCardTitle}>
569
+ {t('crash.jsHeapMemory')}
570
+ </Text>
571
+ </View>
572
+ <CopyButton
573
+ value={selectedCrash.memoryInfo}
574
+ label="Memory Info"
575
+ />
544
576
  </View>
545
577
 
546
578
  <View style={localStyles.diagGrid}>
@@ -566,6 +598,19 @@ const CrashDetail: React.FC = React.memo(() => {
566
598
  {/* 3. BREADCRUMBS TAB */}
567
599
  {activeSubTab === 'breadcrumbs' && (
568
600
  <View style={{gap: 10}}>
601
+ {selectedCrash.breadcrumbs && selectedCrash.breadcrumbs.length > 0 && (
602
+ <View
603
+ style={{
604
+ flexDirection: 'row',
605
+ justifyContent: 'flex-end',
606
+ marginBottom: 2,
607
+ }}>
608
+ <CopyButton
609
+ value={selectedCrash.breadcrumbs}
610
+ label="All Breadcrumbs"
611
+ />
612
+ </View>
613
+ )}
569
614
  {selectedCrash.breadcrumbs && selectedCrash.breadcrumbs.length > 0 ? (
570
615
  selectedCrash.breadcrumbs.map((b, idx) => (
571
616
  <View key={`crumb_${idx}`} style={localStyles.breadcrumbCard}>
@@ -575,9 +620,20 @@ const CrashDetail: React.FC = React.memo(() => {
575
620
  {b.type.toUpperCase()}
576
621
  </Text>
577
622
  </View>
578
- <Text style={localStyles.breadcrumbTime}>
579
- {new Date(b.timestamp).toLocaleTimeString()}
580
- </Text>
623
+ <View
624
+ style={{
625
+ flexDirection: 'row',
626
+ alignItems: 'center',
627
+ gap: 8,
628
+ }}>
629
+ <Text style={localStyles.breadcrumbTime}>
630
+ {new Date(b.timestamp).toLocaleTimeString()}
631
+ </Text>
632
+ <CopyButton
633
+ value={`${new Date(b.timestamp).toLocaleTimeString()} [${b.type.toUpperCase()}] ${b.message}${b.data ? ' ' + JSON.stringify(b.data) : ''}`}
634
+ label="Breadcrumb"
635
+ />
636
+ </View>
581
637
  </View>
582
638
  <Text style={localStyles.breadcrumbMessage}>{b.message}</Text>
583
639
  {b.data && (
@@ -433,9 +433,27 @@ const CrashTab = React.memo(() => {
433
433
  autoCorrect={false}
434
434
  />
435
435
  {searchQuery.length > 0 && (
436
- <TouchableOpacity onPress={() => setSearchQuery('')} hitSlop={8}>
437
- <ClearIcon color={AppColors.grayTextWeak} size={14} />
438
- </TouchableOpacity>
436
+ <View style={{flexDirection: 'row', alignItems: 'center', gap: 4}}>
437
+ <View
438
+ style={{
439
+ backgroundColor: `${AppColors.purple}20`,
440
+ borderRadius: 10,
441
+ paddingHorizontal: 6,
442
+ paddingVertical: 1.5,
443
+ }}>
444
+ <Text
445
+ style={{
446
+ color: AppColors.purple,
447
+ fontSize: 9.5,
448
+ fontFamily: AppFonts.interBold,
449
+ }}>
450
+ {filteredList.length}
451
+ </Text>
452
+ </View>
453
+ <TouchableOpacity onPress={() => setSearchQuery('')} hitSlop={8}>
454
+ <ClearIcon color={AppColors.grayTextWeak} size={14} />
455
+ </TouchableOpacity>
456
+ </View>
439
457
  )}
440
458
  </View>
441
459
 
@@ -539,6 +557,26 @@ const CrashTab = React.memo(() => {
539
557
  ? t('crash.emptySearchSubtitle')
540
558
  : t('crash.emptySubtitle')}
541
559
  </Text>
560
+ {searchQuery.length > 0 && (
561
+ <TouchableScale
562
+ onPress={() => setSearchQuery('')}
563
+ style={{
564
+ marginTop: 10,
565
+ paddingHorizontal: 14,
566
+ paddingVertical: 7,
567
+ borderRadius: 8,
568
+ backgroundColor: AppColors.purple,
569
+ }}>
570
+ <Text
571
+ style={{
572
+ fontFamily: AppFonts.interBold,
573
+ fontSize: 11.5,
574
+ color: AppColors.white,
575
+ }}>
576
+ Clear Search
577
+ </Text>
578
+ </TouchableScale>
579
+ )}
542
580
  </ScrollView>
543
581
  ) : (
544
582
  <FlatList
@@ -86,9 +86,9 @@ const InfoRow = React.memo(
86
86
  styles.infoRow,
87
87
  isLast && {borderBottomWidth: 0},
88
88
  ]}>
89
- <View style={{flex: 1, paddingRight: 8}}>
90
- <View style={{flexDirection: 'row', alignItems: 'center', gap: 6}}>
91
- <Text style={styles.infoLabel}>{label}</Text>
89
+ <View style={{flex: 1, paddingRight: 8, minWidth: 0}}>
90
+ <View style={{flexDirection: 'row', alignItems: 'center', flexWrap: 'wrap', gap: 6}}>
91
+ <Text style={styles.infoLabel} numberOfLines={2}>{label}</Text>
92
92
  {badge && (
93
93
  <View
94
94
  style={[
@@ -101,9 +101,17 @@ const InfoRow = React.memo(
101
101
  </View>
102
102
  )}
103
103
  </View>
104
- {subtext && <Text style={styles.infoSubtext}>{subtext}</Text>}
104
+ {subtext && <Text style={styles.infoSubtext} numberOfLines={2}>{subtext}</Text>}
105
105
  </View>
106
- <View style={{flexDirection: 'row', alignItems: 'center', gap: 8}}>
106
+ <View
107
+ style={{
108
+ flexDirection: 'row',
109
+ alignItems: 'center',
110
+ gap: 6,
111
+ flexShrink: 0,
112
+ maxWidth: '58%',
113
+ justifyContent: 'flex-end',
114
+ }}>
107
115
  <Text
108
116
  style={[
109
117
  styles.infoValue,
@@ -111,7 +119,7 @@ const InfoRow = React.memo(
111
119
  color: value ? AppColors.emerald500 : AppColors.errorColor,
112
120
  },
113
121
  ]}
114
- numberOfLines={2}
122
+ numberOfLines={3}
115
123
  selectable>
116
124
  {displayValue}
117
125
  </Text>
@@ -446,6 +454,16 @@ export const DeviceInfoTab = React.memo(() => {
446
454
  return text.toLowerCase().includes(search.toLowerCase().trim());
447
455
  };
448
456
 
457
+ const hasAnyMatch = useMemo(() => {
458
+ if (!search.trim()) return true;
459
+ const query = search.toLowerCase().trim();
460
+ return (
461
+ JSON.stringify(fullDeviceData).toLowerCase().includes(query) ||
462
+ ipAddress.toLowerCase().includes(query) ||
463
+ pseudoUDID.toLowerCase().includes(query)
464
+ );
465
+ }, [search, fullDeviceData, ipAddress, pseudoUDID]);
466
+
449
467
  return (
450
468
  <View style={styles.container}>
451
469
  {/* ─── Top Sub-Tabs Navigation Bar ─── */}
@@ -527,11 +545,11 @@ export const DeviceInfoTab = React.memo(() => {
527
545
  <AndroidIcon size={20} color={AppColors.white} />
528
546
  )}
529
547
  </View>
530
- <View style={{flex: 1}}>
531
- <Text style={styles.heroTitle}>
548
+ <View style={{flex: 1, minWidth: 0}}>
549
+ <Text style={styles.heroTitle} numberOfLines={1} ellipsizeMode="tail">
532
550
  {deviceMetrics?.deviceModel || (Platform.constants as any)?.Model || (Platform.OS === 'ios' ? 'Apple iPhone' : 'Android Device')}
533
551
  </Text>
534
- <Text style={styles.heroSubtitle}>
552
+ <Text style={styles.heroSubtitle} numberOfLines={1} ellipsizeMode="tail">
535
553
  {Platform.OS === 'ios' ? `iOS ${Platform.Version}` : `Android ${Platform.Version} (API ${deviceMetrics?.apiLevel || Platform.Version})`}
536
554
  </Text>
537
555
  </View>
@@ -544,22 +562,22 @@ export const DeviceInfoTab = React.memo(() => {
544
562
  {/* Quick Metrics Strip */}
545
563
  <View style={styles.heroMetricsStrip}>
546
564
  <View style={styles.heroMetricItem}>
547
- <Text style={styles.heroMetricLabel}>IP ADDRESS</Text>
548
- <Text style={styles.heroMetricValue} numberOfLines={1}>
565
+ <Text style={styles.heroMetricLabel} numberOfLines={1} ellipsizeMode="tail">IP ADDRESS</Text>
566
+ <Text style={styles.heroMetricValue} numberOfLines={1} ellipsizeMode="tail">
549
567
  {ipAddress}
550
568
  </Text>
551
569
  </View>
552
570
  <View style={styles.heroMetricDivider} />
553
571
  <View style={styles.heroMetricItem}>
554
- <Text style={styles.heroMetricLabel}>RAM (USED/TOTAL)</Text>
555
- <Text style={styles.heroMetricValue}>
572
+ <Text style={styles.heroMetricLabel} numberOfLines={1} ellipsizeMode="tail">RAM (USED/TOTAL)</Text>
573
+ <Text style={styles.heroMetricValue} numberOfLines={1} ellipsizeMode="tail">
556
574
  {usedRamMb}/{totalRamMb} MB
557
575
  </Text>
558
576
  </View>
559
577
  <View style={styles.heroMetricDivider} />
560
578
  <View style={styles.heroMetricItem}>
561
- <Text style={styles.heroMetricLabel}>UPTIME</Text>
562
- <Text style={styles.heroMetricValue}>{deviceUptime}</Text>
579
+ <Text style={styles.heroMetricLabel} numberOfLines={1} ellipsizeMode="tail">UPTIME</Text>
580
+ <Text style={styles.heroMetricValue} numberOfLines={1} ellipsizeMode="tail">{deviceUptime}</Text>
563
581
  </View>
564
582
  </View>
565
583
  </View>
@@ -947,6 +965,22 @@ export const DeviceInfoTab = React.memo(() => {
947
965
  </View>
948
966
  )}
949
967
 
968
+ {/* Empty search results state */}
969
+ {search.trim().length > 0 && !hasAnyMatch && (
970
+ <View style={styles.emptySearchCard}>
971
+ <SearchIcon size={26} color={AppColors.grayTextWeak} />
972
+ <Text style={styles.emptySearchTitle}>No matching device specifications</Text>
973
+ <Text style={styles.emptySearchSubtitle}>
974
+ No properties matched &ldquo;{search}&rdquo;
975
+ </Text>
976
+ <TouchableScale
977
+ onPress={() => setSearch('')}
978
+ style={styles.clearSearchBtn}>
979
+ <Text style={styles.clearSearchBtnText}>Clear Search</Text>
980
+ </TouchableScale>
981
+ </View>
982
+ )}
983
+
950
984
  <View style={{height: 48}} />
951
985
  </ScrollView>
952
986
  </View>
@@ -1120,6 +1154,8 @@ const styles = StyleSheet.create({
1120
1154
  heroMetricItem: {
1121
1155
  flex: 1,
1122
1156
  alignItems: 'center',
1157
+ paddingHorizontal: 2,
1158
+ minWidth: 0,
1123
1159
  },
1124
1160
  heroMetricLabel: {
1125
1161
  fontFamily: AppFonts.interBold,
@@ -1191,7 +1227,7 @@ const styles = StyleSheet.create({
1191
1227
  fontFamily: AppFonts.interBold,
1192
1228
  fontSize: 12,
1193
1229
  color: AppColors.primaryBlack,
1194
- maxWidth: 180,
1230
+ flexShrink: 1,
1195
1231
  textAlign: 'right',
1196
1232
  },
1197
1233
  rowCopyBtn: {
@@ -1199,6 +1235,41 @@ const styles = StyleSheet.create({
1199
1235
  borderRadius: 4,
1200
1236
  backgroundColor: AppColors.grayBackground,
1201
1237
  },
1238
+ emptySearchCard: {
1239
+ backgroundColor: AppColors.primaryLight,
1240
+ borderRadius: 14,
1241
+ borderWidth: 1,
1242
+ borderColor: AppColors.grayBorderSecondary,
1243
+ padding: 24,
1244
+ alignItems: 'center',
1245
+ justifyContent: 'center',
1246
+ gap: 8,
1247
+ marginTop: 8,
1248
+ },
1249
+ emptySearchTitle: {
1250
+ fontFamily: AppFonts.interBold,
1251
+ fontSize: 13.5,
1252
+ color: AppColors.primaryBlack,
1253
+ textAlign: 'center',
1254
+ },
1255
+ emptySearchSubtitle: {
1256
+ fontFamily: AppFonts.interRegular,
1257
+ fontSize: 11.5,
1258
+ color: AppColors.grayTextWeak,
1259
+ textAlign: 'center',
1260
+ },
1261
+ clearSearchBtn: {
1262
+ marginTop: 6,
1263
+ paddingHorizontal: 14,
1264
+ paddingVertical: 6.5,
1265
+ borderRadius: 8,
1266
+ backgroundColor: AppColors.purple,
1267
+ },
1268
+ clearSearchBtnText: {
1269
+ fontFamily: AppFonts.interBold,
1270
+ fontSize: 11,
1271
+ color: AppColors.white,
1272
+ },
1202
1273
  });
1203
1274
 
1204
1275
  export default DeviceInfoTab;
@@ -18,7 +18,14 @@ import {AppFonts} from '../../styles/AppFonts';
18
18
  import {METHOD_COLORS} from '../../constants';
19
19
  import {LIB_VERSION} from '../../constants';
20
20
  import {Method} from '../../types';
21
- import {getStatusColor, getAppName, formatTime, getSize} from '../../helpers';
21
+ import {
22
+ getStatusColor,
23
+ getAppName,
24
+ formatTime,
25
+ getSize,
26
+ getAppVersionAndBuild,
27
+ } from '../../helpers';
28
+ import {getNativeDeviceMetrics} from '../../native/NativeInspector';
22
29
  import {UpdateAvailableModal} from './UpdateAvailableModal';
23
30
  import {
24
31
  WhiteBackNavigation,
@@ -71,6 +78,21 @@ const InspectorHeader = React.memo(() => {
71
78
  } = useInspector();
72
79
 
73
80
  const [showUpdateModal, setShowUpdateModal] = React.useState<boolean>(false);
81
+ const [appVersionString, setAppVersionString] = React.useState<string>(() => {
82
+ return getAppVersionAndBuild().formatted;
83
+ });
84
+
85
+ React.useEffect(() => {
86
+ getNativeDeviceMetrics()
87
+ .then(metrics => {
88
+ if (metrics?.appVersion) {
89
+ const v = metrics.appVersion;
90
+ const b = metrics.appBuild || '1';
91
+ setAppVersionString(`${v} (${b})`);
92
+ }
93
+ })
94
+ .catch(() => {});
95
+ }, []);
74
96
 
75
97
  const envConfig = useMemo(() => {
76
98
  const rawEnv = (environment || (__DEV__ ? 'DEV' : 'PROD')).trim();
@@ -375,9 +397,7 @@ const InspectorHeader = React.memo(() => {
375
397
  letterSpacing: 0.1,
376
398
  }}
377
399
  numberOfLines={1}>
378
- {Platform.OS === 'ios'
379
- ? `iOS ${Platform.Version}`
380
- : `Android ${Platform.Version}`}
400
+ {appVersionString}
381
401
  </Text>
382
402
  </View>
383
403
 
@@ -568,10 +568,10 @@ const NetworkDetail = React.memo(() => {
568
568
  />
569
569
 
570
570
  {(() => {
571
- const routeInfo = logRouteMapRef.current.get(
572
- selected.id,
573
- );
574
- if (!routeInfo || routeInfo.path === 'Navigators')
571
+ const routeInfo =
572
+ logRouteMapRef.current.get(selected.id) ||
573
+ (selected as any)?.routeInfo;
574
+ if (!routeInfo || !routeInfo.path || routeInfo.path === 'Navigators')
575
575
  return null;
576
576
  return <SourcePageCard routeInfo={routeInfo} />;
577
577
  })()}