react-native-inapp-inspector 1.1.23 → 1.1.25

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 (79) hide show
  1. package/dist/commonjs/components/AnalyticsEventCard.js +94 -88
  2. package/dist/commonjs/components/ConsoleLogCard.js +49 -25
  3. package/dist/commonjs/components/Inspector/AnalyticsFilterModal.d.ts +7 -0
  4. package/dist/commonjs/components/Inspector/AnalyticsFilterModal.js +1002 -0
  5. package/dist/commonjs/components/Inspector/AnalyticsTab.js +637 -10
  6. package/dist/commonjs/components/Inspector/BundleTab.d.ts +1 -1
  7. package/dist/commonjs/components/Inspector/BundleTab.js +859 -402
  8. package/dist/commonjs/components/Inspector/InspectorContext.js +6 -1
  9. package/dist/commonjs/components/Inspector/InspectorHeader.js +13 -5
  10. package/dist/commonjs/components/Inspector/LogDetail.js +223 -111
  11. package/dist/commonjs/components/Inspector/MainScreen.js +1 -1
  12. package/dist/commonjs/components/Inspector/NetworkDetail.js +131 -81
  13. package/dist/commonjs/components/Inspector/PerformanceTab.js +20 -10
  14. package/dist/commonjs/components/NetworkIcons.d.ts +14 -0
  15. package/dist/commonjs/components/NetworkIcons.js +93 -1
  16. package/dist/commonjs/components/SegmentedTabs.js +31 -22
  17. package/dist/commonjs/components/TreeNode.js +13 -12
  18. package/dist/commonjs/constants/version.d.ts +1 -1
  19. package/dist/commonjs/constants/version.js +1 -1
  20. package/dist/commonjs/customHooks/bundleAnalyzer.d.ts +6 -2
  21. package/dist/commonjs/customHooks/bundleAnalyzer.js +552 -114
  22. package/dist/commonjs/customHooks/consoleLogger.js +83 -45
  23. package/dist/commonjs/customHooks/networkLogger.js +10 -1
  24. package/dist/commonjs/customHooks/performanceTracker.d.ts +8 -0
  25. package/dist/commonjs/customHooks/performanceTracker.js +44 -3
  26. package/dist/commonjs/decorators/index.d.ts +49 -0
  27. package/dist/commonjs/decorators/index.js +142 -0
  28. package/dist/commonjs/helpers/gaAnalyticsRegistry.d.ts +18 -0
  29. package/dist/commonjs/helpers/gaAnalyticsRegistry.js +174 -0
  30. package/dist/commonjs/helpers/index.d.ts +7 -4
  31. package/dist/commonjs/helpers/index.js +102 -64
  32. package/dist/commonjs/i18n/locales/en.json +53 -4
  33. package/dist/commonjs/index.d.ts +4 -0
  34. package/dist/commonjs/index.js +216 -8
  35. package/dist/commonjs/styles/index.d.ts +4 -1
  36. package/dist/commonjs/styles/index.js +22 -19
  37. package/dist/commonjs/types/enums.d.ts +115 -9
  38. package/dist/commonjs/types/enums.js +103 -2
  39. package/dist/commonjs/types/interfaces.d.ts +19 -0
  40. package/dist/esm/components/AnalyticsEventCard.js +95 -89
  41. package/dist/esm/components/ConsoleLogCard.js +49 -25
  42. package/dist/esm/components/Inspector/AnalyticsFilterModal.d.ts +7 -0
  43. package/dist/esm/components/Inspector/AnalyticsFilterModal.js +964 -0
  44. package/dist/esm/components/Inspector/AnalyticsTab.js +639 -12
  45. package/dist/esm/components/Inspector/BundleTab.d.ts +1 -1
  46. package/dist/esm/components/Inspector/BundleTab.js +860 -403
  47. package/dist/esm/components/Inspector/InspectorContext.js +1 -0
  48. package/dist/esm/components/Inspector/InspectorHeader.js +14 -6
  49. package/dist/esm/components/Inspector/LogDetail.js +223 -111
  50. package/dist/esm/components/Inspector/MainScreen.js +2 -2
  51. package/dist/esm/components/Inspector/NetworkDetail.js +132 -49
  52. package/dist/esm/components/Inspector/PerformanceTab.js +20 -10
  53. package/dist/esm/components/NetworkIcons.d.ts +14 -0
  54. package/dist/esm/components/NetworkIcons.js +78 -0
  55. package/dist/esm/components/SegmentedTabs.js +31 -22
  56. package/dist/esm/components/TreeNode.js +13 -12
  57. package/dist/esm/constants/version.d.ts +1 -1
  58. package/dist/esm/constants/version.js +1 -1
  59. package/dist/esm/customHooks/bundleAnalyzer.d.ts +6 -2
  60. package/dist/esm/customHooks/bundleAnalyzer.js +549 -114
  61. package/dist/esm/customHooks/consoleLogger.js +83 -45
  62. package/dist/esm/customHooks/networkLogger.js +10 -1
  63. package/dist/esm/customHooks/performanceTracker.d.ts +8 -0
  64. package/dist/esm/customHooks/performanceTracker.js +38 -1
  65. package/dist/esm/decorators/index.d.ts +49 -0
  66. package/dist/esm/decorators/index.js +137 -0
  67. package/dist/esm/helpers/gaAnalyticsRegistry.d.ts +18 -0
  68. package/dist/esm/helpers/gaAnalyticsRegistry.js +169 -0
  69. package/dist/esm/helpers/index.d.ts +7 -4
  70. package/dist/esm/helpers/index.js +100 -63
  71. package/dist/esm/i18n/locales/en.json +53 -4
  72. package/dist/esm/index.d.ts +4 -0
  73. package/dist/esm/index.js +190 -8
  74. package/dist/esm/styles/index.d.ts +4 -1
  75. package/dist/esm/styles/index.js +22 -19
  76. package/dist/esm/types/enums.d.ts +115 -9
  77. package/dist/esm/types/enums.js +102 -3
  78. package/dist/esm/types/interfaces.d.ts +19 -0
  79. package/package.json +1 -1
@@ -1,7 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.animateNextLayout = exports.useInspector = exports.InspectorContext = void 0;
3
+ exports.animateNextLayout = exports.useInspector = exports.InspectorContext = exports.LogFilter = exports.SettingsSubTab = exports.SettingsPage = exports.ModalAnimationType = void 0;
4
4
  const react_1 = require("react");
5
+ var types_1 = require("../../types");
6
+ Object.defineProperty(exports, "ModalAnimationType", { enumerable: true, get: function () { return types_1.ModalAnimationType; } });
7
+ Object.defineProperty(exports, "SettingsPage", { enumerable: true, get: function () { return types_1.SettingsPage; } });
8
+ Object.defineProperty(exports, "SettingsSubTab", { enumerable: true, get: function () { return types_1.SettingsSubTab; } });
9
+ Object.defineProperty(exports, "LogFilter", { enumerable: true, get: function () { return types_1.LogFilter; } });
5
10
  exports.InspectorContext = (0, react_1.createContext)(null);
6
11
  const useInspector = () => {
7
12
  const ctx = (0, react_1.useContext)(exports.InspectorContext);
@@ -232,10 +232,14 @@ const InspectorHeader = react_1.default.memo(() => {
232
232
  borderColor: `${AppColors_1.AppColors.white}2E`,
233
233
  }}>
234
234
  <react_native_1.View style={{
235
- paddingHorizontal: 5,
236
- paddingVertical: 2,
235
+ flexDirection: 'row',
236
+ alignItems: 'center',
237
+ gap: 3.5,
238
+ paddingHorizontal: 6,
239
+ paddingVertical: 2.5,
237
240
  backgroundColor: `${AppColors_1.AppColors.white}47`,
238
241
  }}>
242
+ {react_native_1.Platform.OS === 'ios' ? (<NetworkIcons_1.AppleIcon color={AppColors_1.AppColors.white} size={10}/>) : (<NetworkIcons_1.AndroidIcon color={AppColors_1.AppColors.white} size={10}/>)}
239
243
  <react_native_1.Text style={{
240
244
  fontFamily: AppFonts_1.AppFonts.interBold,
241
245
  fontSize: 9,
@@ -247,7 +251,7 @@ const InspectorHeader = react_1.default.memo(() => {
247
251
  </react_native_1.View>
248
252
  <react_native_1.View style={{
249
253
  paddingHorizontal: 5,
250
- paddingVertical: 2,
254
+ paddingVertical: 2.5,
251
255
  backgroundColor: `${AppColors_1.AppColors.white}1F`,
252
256
  }}>
253
257
  <react_native_1.Text style={{
@@ -268,10 +272,14 @@ const InspectorHeader = react_1.default.memo(() => {
268
272
  borderColor: `${AppColors_1.AppColors.white}2E`,
269
273
  }}>
270
274
  <react_native_1.View style={{
271
- paddingHorizontal: 5,
272
- paddingVertical: 2,
275
+ flexDirection: 'row',
276
+ alignItems: 'center',
277
+ gap: 3.5,
278
+ paddingHorizontal: 6,
279
+ paddingVertical: 2.5,
273
280
  backgroundColor: `${AppColors_1.AppColors.white}47`,
274
281
  }}>
282
+ <NetworkIcons_1.PackageBoxIcon color={AppColors_1.AppColors.white} size={10}/>
275
283
  <react_native_1.Text style={{
276
284
  fontFamily: AppFonts_1.AppFonts.interBold,
277
285
  fontSize: 9,
@@ -73,6 +73,7 @@ const LogDetail = react_1.default.memo(() => {
73
73
  const jsonContent = (0, react_1.useMemo)(() => (selectedLog ? (0, helpers_1.getJsonContent)(selectedLog.message) : null), [selectedLog]);
74
74
  const [stackViewMode, setStackViewMode] = (0, react_1.useState)('structured');
75
75
  const [stackSource, setStackSource] = (0, react_1.useState)('caller');
76
+ const [stackFilter, setStackFilter] = (0, react_1.useState)('app');
76
77
  const activeStackString = (0, react_1.useMemo)(() => {
77
78
  if (!selectedLog)
78
79
  return '';
@@ -81,21 +82,6 @@ const LogDetail = react_1.default.memo(() => {
81
82
  }
82
83
  return selectedLog.stack || selectedLog.caller || '';
83
84
  }, [selectedLog, stackSource]);
84
- const originFrame = (0, react_1.useMemo)(() => {
85
- if (!selectedLog)
86
- return null;
87
- if (selectedLog.caller && selectedLog.caller !== 'Unknown') {
88
- return (0, helpers_1.parseStackLine)(selectedLog.caller, true);
89
- }
90
- if (selectedLog.stack) {
91
- const firstLine = selectedLog.stack
92
- .split('\n')
93
- .find(l => l.trim().length > 0);
94
- if (firstLine)
95
- return (0, helpers_1.parseStackLine)(firstLine, true);
96
- }
97
- return null;
98
- }, [selectedLog]);
99
85
  const parsedStackFrames = (0, react_1.useMemo)(() => {
100
86
  if (!activeStackString)
101
87
  return [];
@@ -105,6 +91,29 @@ const LogDetail = react_1.default.memo(() => {
105
91
  .filter(l => l.length > 0)
106
92
  .map((line, idx) => (0, helpers_1.parseStackLine)(line, idx === 0));
107
93
  }, [activeStackString]);
94
+ const appStackFrames = (0, react_1.useMemo)(() => {
95
+ return parsedStackFrames.filter(f => f.frameType === 'app' || !f.isRuntimeNoise);
96
+ }, [parsedStackFrames]);
97
+ const displayedFrames = (0, react_1.useMemo)(() => {
98
+ if (stackFilter === 'app' && appStackFrames.length > 0) {
99
+ return appStackFrames;
100
+ }
101
+ return parsedStackFrames;
102
+ }, [stackFilter, appStackFrames, parsedStackFrames]);
103
+ const originFrame = (0, react_1.useMemo)(() => {
104
+ if (!selectedLog)
105
+ return null;
106
+ if (appStackFrames.length > 0) {
107
+ return appStackFrames[0];
108
+ }
109
+ if (selectedLog.caller && selectedLog.caller !== 'Unknown') {
110
+ return (0, helpers_1.parseStackLine)(selectedLog.caller, true);
111
+ }
112
+ if (parsedStackFrames.length > 0) {
113
+ return parsedStackFrames[0];
114
+ }
115
+ return null;
116
+ }, [selectedLog, appStackFrames, parsedStackFrames]);
108
117
  if (!selectedLog)
109
118
  return null;
110
119
  const isDark = AppColors_1.AppColors.primaryLight !== AppColors_1.AppColors.white;
@@ -138,14 +147,14 @@ const LogDetail = react_1.default.memo(() => {
138
147
  const subTabs = [
139
148
  {
140
149
  key: 'output',
141
- label: 'Output',
150
+ label: t('console.tabOutput'),
142
151
  icon: (isActive) => (<NetworkIcons_1.TerminalIcon color={isActive ? AppColors_1.AppColors.white : AppColors_1.AppColors.grayTextWeak} size={12}/>),
143
152
  },
144
153
  ...(hasMultipleArgs
145
154
  ? [
146
155
  {
147
156
  key: 'arguments',
148
- label: `Args (${selectedLog.rawArgs?.length})`,
157
+ label: t('console.tabArgs', { count: selectedLog.rawArgs?.length }),
149
158
  icon: (isActive) => (<NetworkIcons_1.RequestIcon color={isActive ? AppColors_1.AppColors.white : AppColors_1.AppColors.grayTextWeak} size={12}/>),
150
159
  },
151
160
  ]
@@ -154,14 +163,14 @@ const LogDetail = react_1.default.memo(() => {
154
163
  ? [
155
164
  {
156
165
  key: 'stack',
157
- label: 'Stack Trace',
166
+ label: t('console.tabStack'),
158
167
  icon: (isActive) => (<NetworkIcons_1.LayersIcon color={isActive ? AppColors_1.AppColors.white : AppColors_1.AppColors.grayTextWeak} size={12}/>),
159
168
  },
160
169
  ]
161
170
  : []),
162
171
  {
163
172
  key: 'metadata',
164
- label: 'Metadata',
173
+ label: t('console.tabMetadata'),
165
174
  icon: (isActive) => (<NetworkIcons_1.InfoCircleIcon color={isActive ? AppColors_1.AppColors.white : AppColors_1.AppColors.grayTextWeak} size={12}/>),
166
175
  },
167
176
  ];
@@ -613,10 +622,12 @@ const LogDetail = react_1.default.memo(() => {
613
622
  ? AppColors_1.AppColors.primaryLight
614
623
  : AppColors_1.AppColors.grayBackground,
615
624
  }}>
625
+ {/* Header Top Row: Title, Mode switcher & Full copy */}
616
626
  <react_native_1.View style={{
617
627
  flexDirection: 'row',
618
628
  alignItems: 'center',
619
629
  justifyContent: 'space-between',
630
+ gap: 8,
620
631
  }}>
621
632
  <react_native_1.Text style={{
622
633
  fontFamily: AppFonts_1.AppFonts.interBold,
@@ -625,156 +636,257 @@ const LogDetail = react_1.default.memo(() => {
625
636
  textTransform: 'uppercase',
626
637
  letterSpacing: 0.4,
627
638
  }}>
628
- {stackSource === 'error' ? 'Error Exception Stack' : 'Call Stack'} ({parsedStackFrames.length} frames)
639
+ {stackSource === 'error'
640
+ ? t('console.errorStack', { count: parsedStackFrames.length })
641
+ : t('console.callStack', { count: parsedStackFrames.length })}
629
642
  </react_native_1.Text>
630
- <CopyButton_1.default value={activeStackString} label="Full Stack Trace"/>
643
+
644
+ <react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 5 }}>
645
+ <react_native_1.View style={{
646
+ flexDirection: 'row',
647
+ backgroundColor: isDark ? AppColors_1.AppColors.primaryLight : AppColors_1.AppColors.white,
648
+ borderRadius: 7,
649
+ padding: 2,
650
+ borderWidth: 1,
651
+ borderColor: AppColors_1.AppColors.dividerColor,
652
+ }}>
653
+ <react_native_1.Pressable onPress={() => setStackViewMode('structured')} style={{
654
+ flexDirection: 'row',
655
+ alignItems: 'center',
656
+ gap: 3,
657
+ paddingVertical: 3.5,
658
+ paddingHorizontal: 7,
659
+ borderRadius: 5,
660
+ backgroundColor: stackViewMode === 'structured'
661
+ ? AppColors_1.AppColors.brandPurple
662
+ : 'transparent',
663
+ }}>
664
+ <NetworkIcons_1.LayersIcon color={stackViewMode === 'structured'
665
+ ? AppColors_1.AppColors.white
666
+ : AppColors_1.AppColors.grayTextWeak} size={11}/>
667
+ <react_native_1.Text style={{
668
+ fontFamily: AppFonts_1.AppFonts.interBold,
669
+ fontSize: 10,
670
+ color: stackViewMode === 'structured'
671
+ ? AppColors_1.AppColors.white
672
+ : AppColors_1.AppColors.grayTextStrong,
673
+ }}>
674
+ {t('console.cardsView')}
675
+ </react_native_1.Text>
676
+ </react_native_1.Pressable>
677
+
678
+ <react_native_1.Pressable onPress={() => setStackViewMode('raw')} style={{
679
+ flexDirection: 'row',
680
+ alignItems: 'center',
681
+ gap: 3,
682
+ paddingVertical: 3.5,
683
+ paddingHorizontal: 7,
684
+ borderRadius: 5,
685
+ backgroundColor: stackViewMode === 'raw'
686
+ ? AppColors_1.AppColors.brandPurple
687
+ : 'transparent',
688
+ }}>
689
+ <NetworkIcons_1.RawIcon color={stackViewMode === 'raw'
690
+ ? AppColors_1.AppColors.white
691
+ : AppColors_1.AppColors.grayTextWeak} size={11}/>
692
+ <react_native_1.Text style={{
693
+ fontFamily: AppFonts_1.AppFonts.interBold,
694
+ fontSize: 10,
695
+ color: stackViewMode === 'raw'
696
+ ? AppColors_1.AppColors.white
697
+ : AppColors_1.AppColors.grayTextStrong,
698
+ }}>
699
+ {t('console.rawTraceView')}
700
+ </react_native_1.Text>
701
+ </react_native_1.Pressable>
702
+ </react_native_1.View>
703
+
704
+ <CopyButton_1.default value={activeStackString} label={t('console.fullStackTrace')}/>
705
+ </react_native_1.View>
631
706
  </react_native_1.View>
632
707
 
633
708
  {/* Source Switcher if Error Stack exists */}
634
709
  {selectedLog.errorStack && (<SegmentedTabs_1.default tabs={[
635
710
  {
636
711
  key: 'caller',
637
- label: 'Call Origin Stack',
712
+ label: t('console.callOriginStack'),
638
713
  },
639
714
  {
640
715
  key: 'error',
641
- label: 'Error Thrown Stack',
716
+ label: t('console.errorThrownStack'),
642
717
  },
643
718
  ]} activeKey={stackSource} onChange={key => setStackSource(key)}/>)}
644
719
 
645
- {/* Structured vs Raw View Mode Tabs */}
720
+ {/* Scope Filter Tabs (Full Width) */}
646
721
  <SegmentedTabs_1.default tabs={[
647
722
  {
648
- key: 'structured',
649
- label: 'Structured Cards',
650
- icon: (isActive) => (<NetworkIcons_1.LayersIcon color={isActive ? AppColors_1.AppColors.white : AppColors_1.AppColors.grayTextWeak} size={12}/>),
723
+ key: 'app',
724
+ label: t('console.appCodeScope', { count: appStackFrames.length }),
651
725
  },
652
726
  {
653
- key: 'raw',
654
- label: 'Raw Trace',
655
- icon: (isActive) => (<NetworkIcons_1.RawIcon color={isActive ? AppColors_1.AppColors.white : AppColors_1.AppColors.grayTextWeak} size={12}/>),
727
+ key: 'all',
728
+ label: t('console.allFramesScope', { count: parsedStackFrames.length }),
656
729
  },
657
- ]} activeKey={stackViewMode} onChange={key => setStackViewMode(key)}/>
730
+ ]} activeKey={stackFilter} onChange={key => setStackFilter(key)}/>
658
731
  </react_native_1.View>
659
732
 
660
733
  {/* Stack Content: Structured Cards or Raw Full Trace */}
661
734
  {stackViewMode === 'structured' ? (<react_native_1.View style={{ padding: 12, gap: 10 }}>
662
- {parsedStackFrames.length > 0 ? (parsedStackFrames.map((frame, frameIdx) => {
735
+ {displayedFrames.length > 0 ? (displayedFrames.map((frame, frameIdx) => {
663
736
  const isTopFrame = frameIdx === 0;
737
+ const frameBadgeBg = frame.frameType === 'app'
738
+ ? `${AppColors_1.AppColors.brandPurple}15`
739
+ : frame.frameType === 'dependency'
740
+ ? `${AppColors_1.AppColors.amber500}18`
741
+ : frame.frameType === 'native'
742
+ ? `${AppColors_1.AppColors.sky500}18`
743
+ : AppColors_1.AppColors.grayBorderSecondary;
744
+ const frameBadgeText = frame.frameType === 'app'
745
+ ? AppColors_1.AppColors.brandPurple
746
+ : frame.frameType === 'dependency'
747
+ ? AppColors_1.AppColors.amber700
748
+ : frame.frameType === 'native'
749
+ ? AppColors_1.AppColors.sky500
750
+ : AppColors_1.AppColors.grayTextWeak;
664
751
  return (<react_native_1.View key={frameIdx} style={{
665
752
  backgroundColor: isTopFrame
666
753
  ? `${AppColors_1.AppColors.brandPurple}0A`
667
754
  : AppColors_1.AppColors.primaryLight,
668
- borderRadius: 8,
755
+ borderRadius: 10,
669
756
  borderWidth: 1,
670
757
  borderColor: isTopFrame
671
- ? `${AppColors_1.AppColors.brandPurple}30`
758
+ ? `${AppColors_1.AppColors.brandPurple}35`
672
759
  : AppColors_1.AppColors.dividerColor,
673
- padding: 10,
674
- gap: 5,
760
+ padding: 11,
761
+ gap: 6,
675
762
  }}>
676
- {/* Frame Header Row */}
763
+ {/* Frame Top Row: Origin / Category, File, Line badge, Copy */}
677
764
  <react_native_1.View style={{
678
765
  flexDirection: 'row',
679
766
  alignItems: 'center',
680
767
  justifyContent: 'space-between',
681
768
  gap: 6,
682
769
  }}>
683
- <react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 6, flex: 1 }}>
684
- <react_native_1.View style={{
685
- backgroundColor: isTopFrame
686
- ? AppColors_1.AppColors.brandPurple
687
- : AppColors_1.AppColors.grayBorderSecondary,
688
- borderRadius: 4,
689
- paddingHorizontal: 5,
690
- paddingVertical: 1.5,
691
- }}>
692
- <react_native_1.Text style={{
693
- fontFamily: AppFonts_1.AppFonts.interBold,
694
- fontSize: 9,
695
- color: isTopFrame
696
- ? AppColors_1.AppColors.white
697
- : AppColors_1.AppColors.grayTextStrong,
698
- }}>
699
- #{frameIdx + 1}
700
- {isTopFrame ? ' ORIGIN' : ''}
701
- </react_native_1.Text>
702
- </react_native_1.View>
703
-
704
- <HighlightText_1.default text={frame.functionName !== '<anonymous>' ? `${frame.functionName}()` : '<anonymous>'} search={detailSearch} style={{
705
- fontFamily: AppFonts_1.AppFonts.interBold,
706
- fontSize: 12,
707
- color: isTopFrame
708
- ? AppColors_1.AppColors.primaryBlack
709
- : AppColors_1.AppColors.grayTextStrong,
710
- }} highlightStyle={{
711
- backgroundColor: AppColors_1.AppColors.yellowHighlight,
712
- color: AppColors_1.AppColors.primaryBlack,
713
- }}/>
714
- </react_native_1.View>
715
-
716
- {frame.lineNumber && (<react_native_1.View style={{
717
- backgroundColor: `${AppColors_1.AppColors.teal600}15`,
718
- borderColor: `${AppColors_1.AppColors.teal600}30`,
719
- borderWidth: 1,
770
+ <react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 5, flex: 1, flexWrap: 'wrap' }}>
771
+ {isTopFrame && (<react_native_1.View style={{
772
+ backgroundColor: AppColors_1.AppColors.brandPurple,
720
773
  borderRadius: 4,
721
- paddingHorizontal: 6,
774
+ paddingHorizontal: 5,
722
775
  paddingVertical: 1.5,
723
776
  }}>
724
- <react_native_1.Text style={{
777
+ <react_native_1.Text style={{
725
778
  fontFamily: AppFonts_1.AppFonts.interBold,
726
- fontSize: 9.5,
727
- color: AppColors_1.AppColors.teal600,
779
+ fontSize: 8.5,
780
+ color: AppColors_1.AppColors.white,
728
781
  }}>
729
- L{frame.lineNumber}
730
- {frame.columnNumber ? `:C${frame.columnNumber}` : ''}
731
- </react_native_1.Text>
732
- </react_native_1.View>)}
733
- </react_native_1.View>
782
+ {t('console.originBadge')}
783
+ </react_native_1.Text>
784
+ </react_native_1.View>)}
734
785
 
735
- {/* File Path Row */}
736
- <react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 6, flexWrap: 'wrap' }}>
737
- {frame.fileExt && frame.fileExt !== 'other' && (<react_native_1.View style={{
786
+ {frame.fileExt && frame.fileExt !== 'other' && (<react_native_1.View style={{
738
787
  backgroundColor: frame.fileExt === 'tsx' || frame.fileExt === 'ts'
739
788
  ? `${AppColors_1.AppColors.brandPurple}18`
740
789
  : `${AppColors_1.AppColors.teal600}18`,
741
- borderRadius: 3,
742
- paddingHorizontal: 4,
743
- paddingVertical: 1,
790
+ borderRadius: 4,
791
+ paddingHorizontal: 4.5,
792
+ paddingVertical: 1.5,
744
793
  }}>
745
- <react_native_1.Text style={{
794
+ <react_native_1.Text style={{
746
795
  fontFamily: AppFonts_1.AppFonts.interBold,
747
796
  fontSize: 8.5,
748
797
  color: frame.fileExt === 'tsx' || frame.fileExt === 'ts'
749
798
  ? AppColors_1.AppColors.brandPurple
750
799
  : AppColors_1.AppColors.teal600,
751
800
  }}>
752
- {frame.fileExt.toUpperCase()}
753
- </react_native_1.Text>
754
- </react_native_1.View>)}
755
- <react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 3 }}>
756
- <NetworkIcons_1.DocIcon color={isTopFrame ? AppColors_1.AppColors.brandPurple : AppColors_1.AppColors.grayTextWeak} size={10}/>
757
- <react_native_1.Text style={{
758
- fontFamily: AppFonts_1.AppFonts.interMedium,
759
- fontSize: 10.5,
801
+ {frame.fileExt.toUpperCase()}
802
+ </react_native_1.Text>
803
+ </react_native_1.View>)}
804
+
805
+ <react_native_1.Text style={{
806
+ fontFamily: AppFonts_1.AppFonts.interBold,
807
+ fontSize: 11.5,
760
808
  color: isTopFrame
761
809
  ? AppColors_1.AppColors.brandPurple
762
- : AppColors_1.AppColors.grayTextWeak,
810
+ : AppColors_1.AppColors.primaryBlack,
763
811
  }}>
764
- {frame.fileName}
765
- </react_native_1.Text>
812
+ {frame.fileName}
813
+ </react_native_1.Text>
814
+ </react_native_1.View>
815
+
816
+ <react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 4 }}>
817
+ {frame.lineNumber && (<react_native_1.View style={{
818
+ backgroundColor: `${AppColors_1.AppColors.teal600}15`,
819
+ borderColor: `${AppColors_1.AppColors.teal600}30`,
820
+ borderWidth: 1,
821
+ borderRadius: 4,
822
+ paddingHorizontal: 5,
823
+ paddingVertical: 1.5,
824
+ }}>
825
+ <react_native_1.Text style={{
826
+ fontFamily: AppFonts_1.AppFonts.interBold,
827
+ fontSize: 9.5,
828
+ color: AppColors_1.AppColors.teal600,
829
+ }}>
830
+ L{frame.lineNumber}{frame.columnNumber ? `:C${frame.columnNumber}` : ''}
831
+ </react_native_1.Text>
832
+ </react_native_1.View>)}
833
+ <CopyButton_1.default value={frame.copyableLocation} label={frame.fileName}/>
834
+ </react_native_1.View>
766
835
  </react_native_1.View>
836
+
837
+ {/* Middle Row: Function / Symbol Invocation */}
838
+ <react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 5 }}>
839
+ <HighlightText_1.default text={frame.functionName !== '<anonymous>' ? `${frame.functionName}()` : '<anonymous>'} search={detailSearch} style={{
840
+ fontFamily: AppFonts_1.AppFonts.interBold,
841
+ fontSize: 12.5,
842
+ color: AppColors_1.AppColors.primaryBlack,
843
+ }} highlightStyle={{
844
+ backgroundColor: AppColors_1.AppColors.yellowHighlight,
845
+ color: AppColors_1.AppColors.primaryBlack,
846
+ }}/>
767
847
  </react_native_1.View>
768
848
 
769
- {/* Full path */}
770
- {frame.fullPath && frame.fullPath !== frame.fileName && (<react_native_1.Text selectable style={{
771
- fontFamily: AppFonts_1.AppFonts.interRegular,
772
- fontSize: 9.5,
773
- color: AppColors_1.AppColors.grayTextWeak,
774
- lineHeight: 14,
775
- }} numberOfLines={2}>
776
- {frame.fullPath}
777
- </react_native_1.Text>)}
849
+ {/* Bottom Row: Clean Relative Path & Execution Scope Tag */}
850
+ <react_native_1.View style={{
851
+ flexDirection: 'row',
852
+ alignItems: 'center',
853
+ justifyContent: 'space-between',
854
+ backgroundColor: isDark ? `${AppColors_1.AppColors.primaryBlack}25` : AppColors_1.AppColors.grayBackground,
855
+ borderRadius: 6,
856
+ paddingHorizontal: 8,
857
+ paddingVertical: 4.5,
858
+ gap: 6,
859
+ }}>
860
+ <react_native_1.Text selectable style={{
861
+ fontFamily: AppFonts_1.AppFonts.interRegular,
862
+ fontSize: 9.5,
863
+ color: AppColors_1.AppColors.grayTextStrong,
864
+ flex: 1,
865
+ }} numberOfLines={1}>
866
+ 📂 {frame.fullPath}
867
+ </react_native_1.Text>
868
+
869
+ <react_native_1.View style={{
870
+ backgroundColor: frameBadgeBg,
871
+ borderRadius: 4,
872
+ paddingHorizontal: 5,
873
+ paddingVertical: 1.5,
874
+ }}>
875
+ <react_native_1.Text style={{
876
+ fontFamily: AppFonts_1.AppFonts.interBold,
877
+ fontSize: 8.5,
878
+ color: frameBadgeText,
879
+ }}>
880
+ {frame.frameType === 'app'
881
+ ? t('console.appCodeBadge')
882
+ : frame.frameType === 'dependency'
883
+ ? t('console.dependencyBadge')
884
+ : frame.frameType === 'native'
885
+ ? t('console.nativeBadge')
886
+ : t('console.hermesVmBadge')}
887
+ </react_native_1.Text>
888
+ </react_native_1.View>
889
+ </react_native_1.View>
778
890
  </react_native_1.View>);
779
891
  })) : (<react_native_1.Text style={{
780
892
  fontFamily: AppFonts_1.AppFonts.interRegular,
@@ -783,7 +895,7 @@ const LogDetail = react_1.default.memo(() => {
783
895
  textAlign: 'center',
784
896
  paddingVertical: 16,
785
897
  }}>
786
- No call stack trace available for this log.
898
+ {t('console.noStackAvailable')}
787
899
  </react_native_1.Text>)}
788
900
  </react_native_1.View>) : (
789
901
  /* Raw Full Trace Monospace Block */
@@ -75,7 +75,7 @@ const MainScreen = () => {
75
75
  (activeTab === 'logs' && selectedLog != null) ||
76
76
  (activeTab === 'redux' && (selectedReduxSlice != null || selectedReduxAction != null));
77
77
  return (<>
78
- {isEnabled && <FabLauncher_1.default />}
78
+ {(react_native_1.Platform.OS === 'ios' || react_native_1.Platform.OS === 'android') && isEnabled && <FabLauncher_1.default />}
79
79
  <react_native_1.Modal visible={visible} animationType={modalAnimationType} transparent>
80
80
  {visible && (<ErrorBoundary_1.default onClose={closeModal}>
81
81
  <react_native_1.View style={styles_1.default.modalBackdrop}>