react-native-inapp-inspector 2.2.3 → 2.2.4

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 (86) hide show
  1. package/dist/commonjs/components/AnalyticsDetail.js +5 -1
  2. package/dist/commonjs/components/AnalyticsEventCard.js +2 -1
  3. package/dist/commonjs/components/DiffViewer.js +1 -1
  4. package/dist/commonjs/components/Inspector/BundleTab.js +22 -0
  5. package/dist/commonjs/components/Inspector/DeviceInfoTab.d.ts +3 -0
  6. package/dist/commonjs/components/Inspector/DeviceInfoTab.js +835 -0
  7. package/dist/commonjs/components/Inspector/InspectorHeader.js +12 -14
  8. package/dist/commonjs/components/Inspector/LogDetail.js +6 -3
  9. package/dist/commonjs/components/Inspector/MainScreen.js +7 -3
  10. package/dist/commonjs/components/Inspector/NetworkTab.js +92 -15
  11. package/dist/commonjs/components/Inspector/PerformanceTab.js +38 -12
  12. package/dist/commonjs/components/Inspector/SettingsPanel.js +440 -229
  13. package/dist/commonjs/components/Inspector/StorageTab.d.ts +3 -0
  14. package/dist/commonjs/components/Inspector/StorageTab.js +892 -0
  15. package/dist/commonjs/components/Inspector/TabBar.js +14 -0
  16. package/dist/commonjs/components/Inspector/TelemetryConsentModal.js +11 -2
  17. package/dist/commonjs/components/Inspector/UpdateAvailableModal.js +4 -1
  18. package/dist/commonjs/components/NetworkIcons.d.ts +6 -0
  19. package/dist/commonjs/components/NetworkIcons.js +30 -1
  20. package/dist/commonjs/constants/version.d.ts +1 -1
  21. package/dist/commonjs/constants/version.js +1 -1
  22. package/dist/commonjs/customHooks/bundleAnalyzer.js +44 -22
  23. package/dist/commonjs/customHooks/storageInspector.d.ts +67 -0
  24. package/dist/commonjs/customHooks/storageInspector.js +486 -0
  25. package/dist/commonjs/i18n/locales/en.json +8 -2
  26. package/dist/commonjs/index.d.ts +1 -0
  27. package/dist/commonjs/index.js +16 -1
  28. package/dist/commonjs/storage.d.ts +5 -0
  29. package/dist/commonjs/storage.js +18 -0
  30. package/dist/commonjs/types/enums.d.ts +5 -0
  31. package/dist/commonjs/types/enums.js +5 -0
  32. package/dist/esm/components/AnalyticsDetail.js +6 -2
  33. package/dist/esm/components/AnalyticsEventCard.js +2 -1
  34. package/dist/esm/components/DiffViewer.js +1 -1
  35. package/dist/esm/components/Inspector/BundleTab.js +22 -0
  36. package/dist/esm/components/Inspector/DeviceInfoTab.d.ts +3 -0
  37. package/dist/esm/components/Inspector/DeviceInfoTab.js +796 -0
  38. package/dist/esm/components/Inspector/InspectorHeader.js +13 -15
  39. package/dist/esm/components/Inspector/LogDetail.js +7 -4
  40. package/dist/esm/components/Inspector/MainScreen.js +7 -3
  41. package/dist/esm/components/Inspector/NetworkTab.js +93 -16
  42. package/dist/esm/components/Inspector/PerformanceTab.js +39 -13
  43. package/dist/esm/components/Inspector/SettingsPanel.js +441 -230
  44. package/dist/esm/components/Inspector/StorageTab.d.ts +3 -0
  45. package/dist/esm/components/Inspector/StorageTab.js +853 -0
  46. package/dist/esm/components/Inspector/TabBar.js +15 -1
  47. package/dist/esm/components/Inspector/TelemetryConsentModal.js +11 -2
  48. package/dist/esm/components/Inspector/UpdateAvailableModal.js +4 -1
  49. package/dist/esm/components/NetworkIcons.d.ts +6 -0
  50. package/dist/esm/components/NetworkIcons.js +23 -0
  51. package/dist/esm/constants/version.d.ts +1 -1
  52. package/dist/esm/constants/version.js +1 -1
  53. package/dist/esm/customHooks/bundleAnalyzer.js +44 -22
  54. package/dist/esm/customHooks/storageInspector.d.ts +67 -0
  55. package/dist/esm/customHooks/storageInspector.js +469 -0
  56. package/dist/esm/i18n/locales/en.json +8 -2
  57. package/dist/esm/index.d.ts +1 -0
  58. package/dist/esm/index.js +5 -0
  59. package/dist/esm/storage.d.ts +5 -0
  60. package/dist/esm/storage.js +5 -0
  61. package/dist/esm/types/enums.d.ts +5 -0
  62. package/dist/esm/types/enums.js +5 -0
  63. package/package.json +8 -1
  64. package/src/components/AnalyticsDetail.tsx +6 -1
  65. package/src/components/AnalyticsEventCard.tsx +2 -1
  66. package/src/components/DiffViewer.tsx +1 -1
  67. package/src/components/Inspector/BundleTab.tsx +29 -0
  68. package/src/components/Inspector/DeviceInfoTab.tsx +1204 -0
  69. package/src/components/Inspector/InspectorHeader.tsx +13 -14
  70. package/src/components/Inspector/LogDetail.tsx +15 -11
  71. package/src/components/Inspector/MainScreen.tsx +7 -3
  72. package/src/components/Inspector/NetworkTab.tsx +104 -16
  73. package/src/components/Inspector/PerformanceTab.tsx +46 -12
  74. package/src/components/Inspector/SettingsPanel.tsx +570 -304
  75. package/src/components/Inspector/StorageTab.tsx +1048 -0
  76. package/src/components/Inspector/TabBar.tsx +20 -0
  77. package/src/components/Inspector/TelemetryConsentModal.tsx +26 -2
  78. package/src/components/Inspector/UpdateAvailableModal.tsx +13 -1
  79. package/src/components/NetworkIcons.tsx +103 -0
  80. package/src/constants/version.ts +1 -1
  81. package/src/customHooks/bundleAnalyzer.ts +47 -22
  82. package/src/customHooks/storageInspector.ts +509 -0
  83. package/src/i18n/locales/en.json +8 -2
  84. package/src/index.tsx +21 -1
  85. package/src/storage.ts +18 -0
  86. package/src/types/enums.ts +5 -0
@@ -12,7 +12,7 @@ import { LIB_VERSION } from '../../constants';
12
12
  import { getStatusColor, getAppName, formatTime, getSize } from '../../helpers';
13
13
  import { getTelemetryConsentStatus } from '../../helpers/telemetry';
14
14
  import { UpdateAvailableModal } from './UpdateAvailableModal';
15
- import { WhiteBackNavigation, TrashIcon, SettingsIcon, CloseWhite, ClockIcon, SizeIcon, AppleIcon, AndroidIcon, NpmIcon, ResetIcon, } from '../NetworkIcons';
15
+ import { WhiteBackNavigation, TrashIcon, SettingsIcon, CloseWhite, ClockIcon, SizeIcon, AppleIcon, AndroidIcon, NpmIcon, ResetIcon, BoltIcon, } from '../NetworkIcons';
16
16
  const InspectorHeader = React.memo(() => {
17
17
  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, } = useInspector();
18
18
  const [showUpdateModal, setShowUpdateModal] = React.useState(false);
@@ -259,8 +259,9 @@ const InspectorHeader = React.memo(() => {
259
259
  color: '#FFFFFF',
260
260
  letterSpacing: 0.3,
261
261
  }}>
262
- UPDATE
262
+ UPDATE
263
263
  </Text>
264
+ <BoltIcon size={9} color="#FFFFFF"/>
264
265
  </Pressable>)}
265
266
  </View>
266
267
 
@@ -304,26 +305,23 @@ const InspectorHeader = React.memo(() => {
304
305
  Linking.openURL('https://www.npmjs.com/package/react-native-inapp-inspector').catch(() => { });
305
306
  }
306
307
  }} style={{
307
- backgroundColor: '#FFFFFF',
308
+ flexDirection: 'row',
309
+ alignItems: 'center',
310
+ backgroundColor: `${AppColors.white}1F`,
308
311
  borderRadius: 5,
309
312
  paddingHorizontal: 6,
310
313
  paddingVertical: 2,
311
- flexDirection: 'row',
312
- alignItems: 'center',
313
314
  gap: 4,
315
+ borderWidth: 1,
316
+ borderColor: `${AppColors.white}2E`,
314
317
  flexShrink: 0,
315
- shadowColor: '#000000',
316
- shadowOffset: { width: 0, height: 1 },
317
- shadowOpacity: 0.15,
318
- shadowRadius: 2,
319
- elevation: 2,
320
318
  }}>
321
- <NpmIcon size={11} color="#CB3837"/>
319
+ <NpmIcon size={10} color="#FF6B6B"/>
322
320
  <Text style={{
323
- fontFamily: AppFonts.interBold,
321
+ fontFamily: AppFonts.interMedium,
324
322
  fontSize: 9.5,
325
- color: '#CB3837',
326
- letterSpacing: 0.2,
323
+ color: `${AppColors.white}EB`,
324
+ letterSpacing: 0.1,
327
325
  }} numberOfLines={1}>
328
326
  v{LIB_VERSION}
329
327
  </Text>
@@ -332,7 +330,7 @@ const InspectorHeader = React.memo(() => {
332
330
  fontSize: 9,
333
331
  color: '#F59E0B',
334
332
  }}>
335
-
333
+
336
334
  </Text>)}
337
335
  </Pressable>
338
336
 
@@ -6,7 +6,7 @@ import HighlightText from '../HighlightText';
6
6
  import JsonViewer from '../JsonViewer';
7
7
  import CopyButton from '../CopyButton';
8
8
  import SegmentedTabs from '../SegmentedTabs';
9
- import { ClearIcon, SearchIcon, PrettyIcon, RawIcon, TableIcon, LayersIcon, TerminalIcon, RequestIcon, InfoCircleIcon, DocIcon, ExternalLinkIcon, } from '../NetworkIcons';
9
+ import { ClearIcon, SearchIcon, PrettyIcon, RawIcon, TableIcon, LayersIcon, TerminalIcon, RequestIcon, InfoCircleIcon, DocIcon, ExternalLinkIcon, FolderIcon, } from '../NetworkIcons';
10
10
  import { AppColors } from '../../styles/AppColors';
11
11
  import { AppFonts } from '../../styles/AppFonts';
12
12
  import styles from '../../styles';
@@ -856,14 +856,17 @@ const LogDetail = React.memo(() => {
856
856
  paddingVertical: 4.5,
857
857
  gap: 6,
858
858
  }}>
859
- <Text selectable style={{
859
+ <View style={{ flexDirection: 'row', alignItems: 'center', gap: 5, flex: 1 }}>
860
+ <FolderIcon size={12} color={AppColors.grayTextWeak}/>
861
+ <Text selectable style={{
860
862
  fontFamily: AppFonts.interRegular,
861
863
  fontSize: 9.5,
862
864
  color: AppColors.grayTextStrong,
863
865
  flex: 1,
864
866
  }} numberOfLines={1}>
865
- 📂 {frame.fullPath}
866
- </Text>
867
+ {frame.fullPath}
868
+ </Text>
869
+ </View>
867
870
 
868
871
  <View style={{
869
872
  backgroundColor: frameBadgeBg,
@@ -17,6 +17,8 @@ import BundleTab from './BundleTab';
17
17
  import PerformanceTab from './PerformanceTab';
18
18
  import CrashTab from './CrashTab';
19
19
  import CrashDetail from './CrashDetail';
20
+ import DeviceInfoTab from './DeviceInfoTab';
21
+ import StorageTab from './StorageTab';
20
22
  import SettingsPanel from './SettingsPanel';
21
23
  import TelemetryConsentModal from './TelemetryConsentModal';
22
24
  import NpmUpdateToast from './NpmUpdateToast';
@@ -116,6 +118,8 @@ const MainScreen = () => {
116
118
  {activeTab === 'bundle' && <BundleTab />}
117
119
  {activeTab === 'performance' && <PerformanceTab />}
118
120
  {activeTab === 'crash' && <CrashTab />}
121
+ {activeTab === 'device' && <DeviceInfoTab />}
122
+ {activeTab === 'storage' && <StorageTab />}
119
123
  </Animated.View>
120
124
 
121
125
  {/* Detail View Layer - Rendered on top with smooth slide & spring transition */}
@@ -172,14 +176,14 @@ const MainScreen = () => {
172
176
 
173
177
  {/* NPM Version Update Toast with timeout progress bar */}
174
178
  <NpmUpdateToast />
179
+
180
+ {/* Anonymous Telemetry Consent Dialog shown ONLY when inspector is active */}
181
+ <TelemetryConsentModal />
175
182
  </View>
176
183
  </View>
177
184
  </ErrorBoundary>)}
178
185
  {hasNavigationContext && (<NavigationTracker onStateChange={setNavState}/>)}
179
186
  </Modal>
180
-
181
- {/* Anonymous Telemetry Consent Dialog at root viewport */}
182
- <TelemetryConsentModal />
183
187
  </>);
184
188
  };
185
189
  export default MainScreen;
@@ -13,7 +13,7 @@ import { AppColors } from '../../styles/AppColors';
13
13
  import { AppFonts } from '../../styles/AppFonts';
14
14
  import { STATUS_FILTERS, METHOD_COLORS } from '../../constants';
15
15
  import { useTranslation } from '../../i18n';
16
- import { SearchIcon, ClearIcon, TrashIcon, SortArrowIcon, FilterIcon, ChevronIcon, CircleCheckIcon, CircleXIcon, CircleAlertIcon, LayersIcon, HeaderPauseIcon, ClockIcon, } from '../NetworkIcons';
16
+ import { SearchIcon, ClearIcon, TrashIcon, SortArrowIcon, FilterIcon, ChevronIcon, CircleCheckIcon, CircleXIcon, CircleAlertIcon, LayersIcon, HeaderPauseIcon, ClockIcon, GlobeIcon, RequestIcon, ResponseIcon, HeadersIcon, AtomIcon, BoltIcon, ShieldAlertIcon, } from '../NetworkIcons';
17
17
  const STATUS_META = {
18
18
  ALL: { color: AppColors.grayText, Icon: LayersIcon },
19
19
  '2xx': { color: AppColors.greenColor, Icon: CircleCheckIcon },
@@ -182,23 +182,83 @@ const NetworkTab = React.memo(() => {
182
182
  },
183
183
  ], [quickCounts]);
184
184
  const SEARCH_SCOPES = [
185
- { id: 'all', label: 'All' },
186
- { id: 'url', label: 'URL / Path' },
187
- { id: 'reqBody', label: 'Payload' },
188
- { id: 'resBody', label: 'Response' },
189
- { id: 'headers', label: 'Headers' },
185
+ {
186
+ id: 'all',
187
+ label: 'All',
188
+ icon: color => <LayersIcon size={9.5} color={color}/>,
189
+ },
190
+ {
191
+ id: 'url',
192
+ label: 'URL / Path',
193
+ icon: color => <GlobeIcon size={9.5} color={color}/>,
194
+ },
195
+ {
196
+ id: 'reqBody',
197
+ label: 'Payload',
198
+ icon: color => <RequestIcon size={9.5} color={color}/>,
199
+ },
200
+ {
201
+ id: 'resBody',
202
+ label: 'Response',
203
+ icon: color => <ResponseIcon size={9.5} color={color}/>,
204
+ },
205
+ {
206
+ id: 'headers',
207
+ label: 'Headers',
208
+ icon: color => <HeadersIcon size={9.5} color={color}/>,
209
+ },
190
210
  ];
191
211
  const QUICK_API_QUERY_TAGS = useMemo(() => [
192
- { label: '⚠️ Failed', query: 'is:error' },
193
- { label: '🐢 Slow >1s', query: 'slow:>1s' },
194
- { label: 'POST', query: 'm:POST' },
195
- { label: 'GET', query: 'm:GET' },
196
- { label: 'GraphQL', query: 'is:graphql' },
197
- { label: 'Axios', query: 'client:axios' },
198
- { label: '200 OK', query: 'status:200' },
199
- { label: '404', query: 'status:404' },
200
- { label: '500', query: 'status:500' },
201
- { label: '🔒 HTTPS', query: 'is:https' },
212
+ {
213
+ label: 'Failed',
214
+ query: 'is:error',
215
+ icon: (color) => <CircleXIcon size={9.5} color={color}/>,
216
+ },
217
+ {
218
+ label: 'Slow (>1s)',
219
+ query: 'slow:>1s',
220
+ icon: (color) => <ClockIcon size={9.5} color={color}/>,
221
+ },
222
+ {
223
+ label: 'POST',
224
+ query: 'm:POST',
225
+ icon: (color) => <RequestIcon size={9.5} color={color}/>,
226
+ },
227
+ {
228
+ label: 'GET',
229
+ query: 'm:GET',
230
+ icon: (color) => <ResponseIcon size={9.5} color={color}/>,
231
+ },
232
+ {
233
+ label: 'GraphQL',
234
+ query: 'is:graphql',
235
+ icon: (color) => <AtomIcon size={9.5} color={color}/>,
236
+ },
237
+ {
238
+ label: 'Axios',
239
+ query: 'client:axios',
240
+ icon: (color) => <BoltIcon size={9.5} color={color}/>,
241
+ },
242
+ {
243
+ label: '200 OK',
244
+ query: 'status:200',
245
+ icon: (color) => <CircleCheckIcon size={9.5} color={color}/>,
246
+ },
247
+ {
248
+ label: '404',
249
+ query: 'status:404',
250
+ icon: (color) => <CircleAlertIcon size={9.5} color={color}/>,
251
+ },
252
+ {
253
+ label: '500',
254
+ query: 'status:500',
255
+ icon: (color) => <CircleXIcon size={9.5} color={color}/>,
256
+ },
257
+ {
258
+ label: 'HTTPS',
259
+ query: 'is:https',
260
+ icon: (color) => <ShieldAlertIcon size={9.5} color={color}/>,
261
+ },
202
262
  ], []);
203
263
  const networkMetrics = useMemo(() => {
204
264
  if (!logs || logs.length === 0)
@@ -481,6 +541,7 @@ const NetworkTab = React.memo(() => {
481
541
  {QUICK_CHIPS.map(chip => {
482
542
  const isActive = quickFilter === chip.id;
483
543
  const chipColor = chip.color || AppColors.purple;
544
+ const iconColor = isActive ? AppColors.white : chipColor;
484
545
  return (<TouchableScale key={chip.id} onPress={() => {
485
546
  setQuickFilter(isActive ? 'all' : chip.id);
486
547
  }}>
@@ -499,6 +560,13 @@ const NetworkTab = React.memo(() => {
499
560
  : `${chipColor}30`,
500
561
  gap: 5,
501
562
  }}>
563
+ {chip.id === 'all' && <LayersIcon size={11} color={iconColor}/>}
564
+ {chip.id === 'errors' && <CircleXIcon size={11} color={iconColor}/>}
565
+ {chip.id === 'success' && <CircleCheckIcon size={11} color={iconColor}/>}
566
+ {chip.id === 'slow' && <ClockIcon size={11} color={iconColor}/>}
567
+ {chip.id === 'POST' && <RequestIcon size={11} color={iconColor}/>}
568
+ {chip.id === 'GET' && <ResponseIcon size={11} color={iconColor}/>}
569
+ {chip.id === 'graphql' && <AtomIcon size={11} color={iconColor}/>}
502
570
  <Text style={{
503
571
  fontFamily: AppFonts.interBold,
504
572
  fontSize: 10.5,
@@ -554,8 +622,12 @@ const NetworkTab = React.memo(() => {
554
622
  }}>
555
623
  {SEARCH_SCOPES.map(s => {
556
624
  const isSelected = searchScope === s.id;
625
+ const iconColor = isSelected ? AppColors.white : AppColors.grayText;
557
626
  return (<TouchableScale key={s.id} onPress={() => setSearchScope(s.id)}>
558
627
  <View style={{
628
+ flexDirection: 'row',
629
+ alignItems: 'center',
630
+ gap: 4,
559
631
  paddingHorizontal: 7,
560
632
  paddingVertical: 2.5,
561
633
  borderRadius: 5,
@@ -567,6 +639,7 @@ const NetworkTab = React.memo(() => {
567
639
  ? AppColors.purple
568
640
  : AppColors.grayBorderSecondary,
569
641
  }}>
642
+ {s.icon(iconColor)}
570
643
  <Text style={{
571
644
  fontFamily: AppFonts.interBold,
572
645
  fontSize: 9.5,
@@ -600,6 +673,9 @@ const NetworkTab = React.memo(() => {
600
673
  }
601
674
  }}>
602
675
  <View style={{
676
+ flexDirection: 'row',
677
+ alignItems: 'center',
678
+ gap: 4,
603
679
  paddingHorizontal: 7,
604
680
  paddingVertical: 2.5,
605
681
  borderRadius: 5,
@@ -611,6 +687,7 @@ const NetworkTab = React.memo(() => {
611
687
  ? AppColors.purple
612
688
  : `${AppColors.purple}30`,
613
689
  }}>
690
+ {item.icon(isSelected ? AppColors.white : AppColors.purple)}
614
691
  <Text style={{
615
692
  fontFamily: AppFonts.interBold,
616
693
  fontSize: 9.5,
@@ -9,7 +9,7 @@ import { AppColors } from '../../styles/AppColors';
9
9
  import { AppFonts } from '../../styles/AppFonts';
10
10
  import { useTranslation } from '../../i18n';
11
11
  import { getRuntimeDiagnostics } from '../../helpers';
12
- import { SearchIcon, CircleXIcon, PerformanceIcon, BoltIcon, LightbulbIcon, } from '../NetworkIcons';
12
+ import { SearchIcon, CircleXIcon, CircleAlertIcon, PerformanceIcon, BoltIcon, LightbulbIcon, MapIcon, AtomIcon, BrainIcon, GlobeIcon, ChevronIcon, } from '../NetworkIcons';
13
13
  import { getPerformanceEvents, subscribePerformanceEvents, logPerformanceEvent, clearPerformanceEvents, } from '../../customHooks/performanceTracker';
14
14
  import { startNativeFpsMonitoring, stopNativeFpsMonitoring, getNativeFpsMetrics, getNativeSystemMetrics, isNativeModuleAvailable, } from '../../native/NativeInspector';
15
15
  const PerformanceTab = React.memo(() => {
@@ -373,18 +373,45 @@ const PerformanceTab = React.memo(() => {
373
373
  <View style={perfStyles.categoryScrollWrapper}>
374
374
  <ScrollView horizontal showsHorizontalScrollIndicator={false} style={perfStyles.categoryScrollView} contentContainerStyle={perfStyles.categoryScroll}>
375
375
  {[
376
- { key: 'ALL', label: t('performance.catAll') },
377
- { key: 'JANKY', label: t('performance.catJanky') },
378
- { key: 'NAVIGATION', label: t('performance.catNavigation') },
379
- { key: 'RENDER', label: t('performance.catRender') },
380
- { key: 'MEMORY', label: t('performance.catMemory') },
381
- { key: 'IO', label: t('performance.catIo') },
376
+ {
377
+ key: 'ALL',
378
+ label: t('performance.catAll'),
379
+ icon: (color) => <PerformanceIcon size={12} color={color}/>,
380
+ },
381
+ {
382
+ key: 'JANKY',
383
+ label: t('performance.catJanky'),
384
+ icon: (color) => <CircleAlertIcon size={12} color={color}/>,
385
+ },
386
+ {
387
+ key: 'NAVIGATION',
388
+ label: t('performance.catNavigation'),
389
+ icon: (color) => <MapIcon size={12} color={color}/>,
390
+ },
391
+ {
392
+ key: 'RENDER',
393
+ label: t('performance.catRender'),
394
+ icon: (color) => <AtomIcon size={12} color={color}/>,
395
+ },
396
+ {
397
+ key: 'MEMORY',
398
+ label: t('performance.catMemory'),
399
+ icon: (color) => <BrainIcon size={12} color={color}/>,
400
+ },
401
+ {
402
+ key: 'IO',
403
+ label: t('performance.catIo'),
404
+ icon: (color) => <GlobeIcon size={12} color={color}/>,
405
+ },
382
406
  ].map(cat => {
383
407
  const isSelected = filterCategory === cat.key;
408
+ const iconColor = isSelected ? AppColors.white : AppColors.grayTextWeak;
384
409
  return (<TouchableScale key={cat.key} onPress={() => setFilterCategory(cat.key)} style={[
385
410
  perfStyles.categoryChip,
386
411
  isSelected && perfStyles.categoryChipActive,
412
+ { flexDirection: 'row', alignItems: 'center', gap: 5 },
387
413
  ]}>
414
+ {cat.icon(iconColor)}
388
415
  <Text style={[
389
416
  perfStyles.categoryChipText,
390
417
  isSelected && perfStyles.categoryChipTextActive,
@@ -806,12 +833,13 @@ const PerformanceTab = React.memo(() => {
806
833
  </View>
807
834
 
808
835
  {/* Bottleneck Thread Tag */}
809
- {event.bottleneckThread && (<View style={perfStyles.bottleneckTag}>
836
+ {event.bottleneckThread && (<View style={[perfStyles.bottleneckTag, { flexDirection: 'row', alignItems: 'center', gap: 3 }]}>
837
+ {event.bottleneckThread === 'JS Thread' && (<BoltIcon size={10} color={AppColors.warningIconGold}/>)}
810
838
  <Text style={perfStyles.bottleneckTagText}>
811
839
  {event.bottleneckThread === 'JS Thread'
812
- ? `⚡ ${t('performance.jsBound')}`
840
+ ? t('performance.jsBound')
813
841
  : event.bottleneckThread === 'UI Thread'
814
- ? `🎨 ${t('performance.uiBound')}`
842
+ ? t('performance.uiBound')
815
843
  : t('performance.balanced')}
816
844
  </Text>
817
845
  </View>)}
@@ -819,9 +847,7 @@ const PerformanceTab = React.memo(() => {
819
847
 
820
848
  <View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
821
849
  <CopyButton value={() => event} label={t('common.copyJson')}/>
822
- <Text style={perfStyles.expandChevron}>
823
- {isExpanded ? '▲' : '▼'}
824
- </Text>
850
+ <ChevronIcon isExpanded={isExpanded} size={14} color={AppColors.grayTextWeak}/>
825
851
  </View>
826
852
  </View>
827
853