react-native-inapp-inspector 1.1.35 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/README.md +123 -101
  2. package/android/build.gradle +13 -1
  3. package/android/src/main/java/com/inappinspector/NetworkInspectorModule.kt +890 -0
  4. package/android/src/main/java/com/inappinspector/NetworkInspectorPackage.kt +17 -0
  5. package/dist/commonjs/components/ConsoleLogCard.js +5 -5
  6. package/dist/commonjs/components/CopyButton.js +3 -0
  7. package/dist/commonjs/components/EndOfListFooter.js +1 -1
  8. package/dist/commonjs/components/ErrorBoundary.js +3 -0
  9. package/dist/commonjs/components/Inspector/AnalyticsTab.js +25 -73
  10. package/dist/commonjs/components/Inspector/BundleTab.js +671 -189
  11. package/dist/commonjs/components/Inspector/ConsoleTab.js +110 -99
  12. package/dist/commonjs/components/Inspector/CrashTab.js +99 -91
  13. package/dist/commonjs/components/Inspector/InspectorHeader.js +107 -20
  14. package/dist/commonjs/components/Inspector/MainScreen.js +111 -68
  15. package/dist/commonjs/components/Inspector/NetworkTab.js +151 -30
  16. package/dist/commonjs/components/Inspector/PerformanceTab.js +96 -3
  17. package/dist/commonjs/components/Inspector/ReduxTab.js +18 -10
  18. package/dist/commonjs/components/Inspector/SettingsPanel.js +1218 -1238
  19. package/dist/commonjs/components/Inspector/TabBar.js +4 -2
  20. package/dist/commonjs/components/JsonViewer.js +9 -4
  21. package/dist/commonjs/components/LogCard.js +31 -1
  22. package/dist/commonjs/components/LogSyntaxHighlighter.d.ts +16 -0
  23. package/dist/commonjs/components/LogSyntaxHighlighter.js +130 -0
  24. package/dist/commonjs/components/NetworkIcons.d.ts +3 -0
  25. package/dist/commonjs/components/NetworkIcons.js +15 -1
  26. package/dist/commonjs/components/Slider.d.ts +13 -0
  27. package/dist/commonjs/components/Slider.js +261 -0
  28. package/dist/commonjs/components/TouchableScale.d.ts +1 -0
  29. package/dist/commonjs/components/TouchableScale.js +30 -32
  30. package/dist/commonjs/constants/index.d.ts +1 -2
  31. package/dist/commonjs/constants/index.js +4 -0
  32. package/dist/commonjs/constants/version.d.ts +1 -1
  33. package/dist/commonjs/constants/version.js +1 -1
  34. package/dist/commonjs/customHooks/analyticsLogger.d.ts +4 -0
  35. package/dist/commonjs/customHooks/analyticsLogger.js +8 -6
  36. package/dist/commonjs/customHooks/crashHandler.js +8 -1
  37. package/dist/commonjs/helpers/index.d.ts +1 -0
  38. package/dist/commonjs/helpers/index.js +25 -1
  39. package/dist/commonjs/helpers/searchQueryParser.d.ts +6 -0
  40. package/dist/commonjs/helpers/searchQueryParser.js +236 -0
  41. package/dist/commonjs/helpers/settingsStore.d.ts +9 -0
  42. package/dist/commonjs/helpers/settingsStore.js +59 -3
  43. package/dist/commonjs/index.d.ts +1 -0
  44. package/dist/commonjs/index.js +220 -43
  45. package/dist/commonjs/native/NativeInspector.d.ts +125 -0
  46. package/dist/commonjs/native/NativeInspector.js +313 -0
  47. package/dist/commonjs/native/NativeNetworkInspector.d.ts +22 -0
  48. package/dist/commonjs/native/NativeNetworkInspector.js +4 -0
  49. package/dist/commonjs/styles/index.js +41 -41
  50. package/dist/commonjs/types/enums.d.ts +1 -1
  51. package/dist/commonjs/types/interfaces.d.ts +9 -0
  52. package/dist/esm/components/ConsoleLogCard.js +5 -5
  53. package/dist/esm/components/CopyButton.js +3 -0
  54. package/dist/esm/components/EndOfListFooter.js +2 -2
  55. package/dist/esm/components/ErrorBoundary.js +3 -0
  56. package/dist/esm/components/Inspector/AnalyticsTab.js +27 -75
  57. package/dist/esm/components/Inspector/BundleTab.js +671 -189
  58. package/dist/esm/components/Inspector/ConsoleTab.js +111 -100
  59. package/dist/esm/components/Inspector/CrashTab.js +99 -91
  60. package/dist/esm/components/Inspector/InspectorHeader.js +108 -21
  61. package/dist/esm/components/Inspector/MainScreen.js +113 -70
  62. package/dist/esm/components/Inspector/NetworkTab.js +152 -31
  63. package/dist/esm/components/Inspector/PerformanceTab.js +96 -3
  64. package/dist/esm/components/Inspector/ReduxTab.js +18 -10
  65. package/dist/esm/components/Inspector/SettingsPanel.js +1222 -1242
  66. package/dist/esm/components/Inspector/TabBar.js +4 -2
  67. package/dist/esm/components/JsonViewer.js +9 -4
  68. package/dist/esm/components/LogCard.js +32 -2
  69. package/dist/esm/components/LogSyntaxHighlighter.d.ts +16 -0
  70. package/dist/esm/components/LogSyntaxHighlighter.js +123 -0
  71. package/dist/esm/components/NetworkIcons.d.ts +3 -0
  72. package/dist/esm/components/NetworkIcons.js +11 -0
  73. package/dist/esm/components/Slider.d.ts +13 -0
  74. package/dist/esm/components/Slider.js +222 -0
  75. package/dist/esm/components/TouchableScale.d.ts +1 -0
  76. package/dist/esm/components/TouchableScale.js +31 -33
  77. package/dist/esm/constants/index.d.ts +1 -2
  78. package/dist/esm/constants/index.js +4 -0
  79. package/dist/esm/constants/version.d.ts +1 -1
  80. package/dist/esm/constants/version.js +1 -1
  81. package/dist/esm/customHooks/analyticsLogger.d.ts +4 -0
  82. package/dist/esm/customHooks/analyticsLogger.js +6 -5
  83. package/dist/esm/customHooks/crashHandler.js +8 -1
  84. package/dist/esm/helpers/index.d.ts +1 -0
  85. package/dist/esm/helpers/index.js +11 -1
  86. package/dist/esm/helpers/searchQueryParser.d.ts +6 -0
  87. package/dist/esm/helpers/searchQueryParser.js +233 -0
  88. package/dist/esm/helpers/settingsStore.d.ts +9 -0
  89. package/dist/esm/helpers/settingsStore.js +58 -3
  90. package/dist/esm/index.d.ts +1 -0
  91. package/dist/esm/index.js +207 -44
  92. package/dist/esm/native/NativeInspector.d.ts +125 -0
  93. package/dist/esm/native/NativeInspector.js +289 -0
  94. package/dist/esm/native/NativeNetworkInspector.d.ts +22 -0
  95. package/dist/esm/native/NativeNetworkInspector.js +2 -0
  96. package/dist/esm/styles/index.js +41 -41
  97. package/dist/esm/types/enums.d.ts +1 -1
  98. package/dist/esm/types/interfaces.d.ts +9 -0
  99. package/ios/NetworkInspectorModule.h +6 -0
  100. package/ios/NetworkInspectorModule.m +760 -5
  101. package/package.json +13 -2
  102. package/react-native-inapp-inspector.podspec +7 -2
  103. package/android/src/main/java/com/inappinspector/NetworkInspectorModule.java +0 -97
  104. package/android/src/main/java/com/inappinspector/NetworkInspectorPackage.java +0 -28
@@ -0,0 +1,17 @@
1
+ package com.inappinspector
2
+
3
+ import com.facebook.react.ReactPackage
4
+ import com.facebook.react.bridge.NativeModule
5
+ import com.facebook.react.bridge.ReactApplicationContext
6
+ import com.facebook.react.uimanager.ViewManager
7
+ import java.util.Collections
8
+
9
+ class NetworkInspectorPackage : ReactPackage {
10
+ override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
11
+ return listOf(NetworkInspectorModule(reactContext))
12
+ }
13
+
14
+ override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
15
+ return Collections.emptyList()
16
+ }
17
+ }
@@ -10,8 +10,8 @@ const react_native_1 = require("react-native");
10
10
  const AppColors_1 = require("../styles/AppColors");
11
11
  const AppFonts_1 = require("../styles/AppFonts");
12
12
  const helpers_1 = require("../helpers");
13
- const HighlightText_1 = __importDefault(require("./HighlightText"));
14
13
  const CopyButton_1 = __importDefault(require("./CopyButton"));
14
+ const LogSyntaxHighlighter_1 = __importDefault(require("./LogSyntaxHighlighter"));
15
15
  const NetworkIcons_1 = require("./NetworkIcons");
16
16
  const InspectorContext_1 = require("./Inspector/InspectorContext");
17
17
  const getLogMessageWithBadges = (message, searchStr, textStyle, highlightStyle, numberOfLines) => {
@@ -79,10 +79,10 @@ const getLogMessageWithBadges = (message, searchStr, textStyle, highlightStyle,
79
79
  </react_native_1.View>);
80
80
  })}
81
81
  </react_native_1.View>
82
- <HighlightText_1.default text={remainingText} search={searchStr} style={textStyle} highlightStyle={highlightStyle} numberOfLines={numberOfLines} detectLinks={true}/>
82
+ <LogSyntaxHighlighter_1.default text={remainingText} search={searchStr} style={textStyle} numberOfLines={numberOfLines} detectLinks={true}/>
83
83
  </react_native_1.View>);
84
84
  }
85
- return (<HighlightText_1.default text={message} search={searchStr} style={textStyle} highlightStyle={highlightStyle} numberOfLines={numberOfLines} detectLinks={true}/>);
85
+ return (<LogSyntaxHighlighter_1.default text={message} search={searchStr} style={textStyle} numberOfLines={numberOfLines} detectLinks={true}/>);
86
86
  };
87
87
  exports.ConsoleLogCard = react_1.default.memo(function ConsoleLogCard({ item, searchStr = '', }) {
88
88
  const { setSelectedLog } = (0, InspectorContext_1.useInspector)();
@@ -240,10 +240,10 @@ exports.ConsoleLogCard = react_1.default.memo(function ConsoleLogCard({ item, se
240
240
  {jsonContent ? (<>
241
241
  {jsonContent.header ? (getLogMessageWithBadges(jsonContent.header, searchStr, [styles.messageText, { color: AppColors_1.AppColors.primaryBlack }], styles.highlight, 2)) : null}
242
242
  {jsonPreview && (<react_native_1.View style={styles.jsonPreviewContainer}>
243
- <HighlightText_1.default text={jsonPreview.text} search={searchStr} style={[
243
+ <LogSyntaxHighlighter_1.default text={jsonPreview.text} search={searchStr} style={[
244
244
  styles.jsonPreviewText,
245
245
  { color: AppColors_1.AppColors.primaryBlack },
246
- ]} highlightStyle={styles.highlight} detectLinks={false} numberOfLines={5}/>
246
+ ]} detectLinks={false} numberOfLines={5}/>
247
247
  </react_native_1.View>)}
248
248
  </>) : (getLogMessageWithBadges(item.message, searchStr, [styles.messageText, { color: AppColors_1.AppColors.primaryBlack }], styles.highlight, 3))}
249
249
  </react_native_1.View>
@@ -42,6 +42,7 @@ const react_native_1 = require("react-native");
42
42
  const TouchableScale_1 = __importDefault(require("./TouchableScale"));
43
43
  // Helpers
44
44
  const helpers_1 = require("../helpers");
45
+ const NativeInspector_1 = require("../native/NativeInspector");
45
46
  // Assets
46
47
  const NetworkIcons_1 = require("./NetworkIcons");
47
48
  // Stylesheet
@@ -50,6 +51,7 @@ const styles_1 = __importDefault(require("../styles"));
50
51
  const CopyButton = react_1.default.memo(({ value, label, iconType = 'copy' }) => {
51
52
  const [copied, setCopied] = (0, react_1.useState)(false);
52
53
  const handlePress = (0, react_1.useCallback)(() => {
54
+ (0, NativeInspector_1.triggerNativeHaptic)('success');
53
55
  const resolvedValue = typeof value === 'function' ? value() : value;
54
56
  (0, helpers_1.copyToClipboard)(resolvedValue, label);
55
57
  setCopied(true);
@@ -57,6 +59,7 @@ const CopyButton = react_1.default.memo(({ value, label, iconType = 'copy' }) =>
57
59
  }, [value, label]);
58
60
  const handleLongPress = (0, react_1.useCallback)(() => {
59
61
  try {
62
+ (0, NativeInspector_1.triggerNativeHaptic)('medium');
60
63
  const resolvedValue = typeof value === 'function' ? value() : value;
61
64
  const textToShare = typeof resolvedValue === 'string'
62
65
  ? resolvedValue
@@ -33,7 +33,7 @@ const styles = react_native_1.StyleSheet.create({
33
33
  justifyContent: 'center',
34
34
  paddingHorizontal: 16,
35
35
  paddingTop: 16,
36
- paddingBottom: 28,
36
+ paddingBottom: react_native_1.Platform.OS === 'ios' ? 44 : 32,
37
37
  gap: 8,
38
38
  },
39
39
  dividerLine: {
@@ -43,6 +43,7 @@ const i18n_1 = require("../i18n");
43
43
  const NetworkIcons_1 = require("./NetworkIcons");
44
44
  const crashHandler_1 = require("../customHooks/crashHandler");
45
45
  const enums_1 = require("../types/enums");
46
+ const NativeInspector_1 = require("../native/NativeInspector");
46
47
  function parseStackTrace(stack) {
47
48
  if (!stack)
48
49
  return { rootFrame: null, frames: [] };
@@ -145,6 +146,8 @@ ${error.stack || 'No stack trace available'}
145
146
  try {
146
147
  const stack = error?.stack || errorInfo?.componentStack || '';
147
148
  (0, crashHandler_1.handleInterceptedCrash)(error, stack, false, enums_1.CrashType.Render, errorInfo?.componentStack);
149
+ (0, NativeInspector_1.showNativeFloatingButton)();
150
+ (0, NativeInspector_1.setNativeFloatingButtonBadge)(true);
148
151
  }
149
152
  catch { }
150
153
  }
@@ -40,7 +40,6 @@ const react_1 = __importStar(require("react"));
40
40
  const react_native_1 = require("react-native");
41
41
  const InspectorContext_1 = require("./InspectorContext");
42
42
  const AnalyticsEventCard_1 = __importDefault(require("../AnalyticsEventCard"));
43
- const AnalyticsDetail_1 = __importDefault(require("../AnalyticsDetail"));
44
43
  const AnalyticsFilterModal_1 = __importDefault(require("./AnalyticsFilterModal"));
45
44
  const EndOfListFooter_1 = __importDefault(require("../EndOfListFooter"));
46
45
  const styles_1 = __importDefault(require("../../styles"));
@@ -59,6 +58,10 @@ const AnalyticsHeader = react_1.default.memo(() => {
59
58
  const userProperties = (0, analyticsLogger_1.getCurrentUserProperties)();
60
59
  const defaultParams = (0, analyticsLogger_1.getDefaultEventParameters)();
61
60
  const isTrackingEnabled = (0, analyticsLogger_1.getCollectionEnabled)();
61
+ // If there are no analytics events in the session, hide the graph, category breakdown, and realtime card
62
+ if (analyticsEvents.length === 0) {
63
+ return null;
64
+ }
62
65
  const hasUserProps = Object.keys(userProperties).length > 0;
63
66
  const hasDefaultParams = Object.keys(defaultParams).length > 0;
64
67
  const totalEvents = filteredAnalyticsEvents.length;
@@ -157,16 +160,25 @@ const AnalyticsHeader = react_1.default.memo(() => {
157
160
  return { ...prev, categories: nextCategories };
158
161
  });
159
162
  };
160
- // 12-Bucket GA4 Realtime Stacked Histogram & Spline Wave Graph (-30m / 30s to NOW)
163
+ // 12-Bucket GA4 Realtime Stacked Histogram & Spline Wave Graph (60s live rolling stream)
161
164
  const BUCKET_COUNT = 12;
162
165
  const chartHeight = 64;
163
166
  const svgWidth = 320;
164
167
  const [selectedBucketIdx, setSelectedBucketIdx] = (0, react_1.useState)(null);
168
+ const [liveTick, setLiveTick] = (0, react_1.useState)(0);
169
+ (0, react_1.useEffect)(() => {
170
+ if (!isTrackingEnabled)
171
+ return;
172
+ const interval = setInterval(() => {
173
+ setLiveTick(t => (t + 1) % 100000);
174
+ }, 1000);
175
+ return () => clearInterval(interval);
176
+ }, [isTrackingEnabled]);
165
177
  const histogramData = (0, react_1.useMemo)(() => {
166
178
  const buckets = [];
167
179
  const now = Date.now();
168
- const windowMs = 60000; // 60s window
169
- const bucketDuration = windowMs / BUCKET_COUNT;
180
+ const windowMs = 60000; // 60s live rolling window
181
+ const bucketDuration = windowMs / BUCKET_COUNT; // 5s per bucket
170
182
  for (let i = 0; i < BUCKET_COUNT; i++) {
171
183
  const bucketAgeSec = Math.round(((BUCKET_COUNT - 1 - i) * bucketDuration) / 1000);
172
184
  buckets.push({
@@ -231,7 +243,7 @@ const AnalyticsHeader = react_1.default.memo(() => {
231
243
  peakVal,
232
244
  eventRate,
233
245
  };
234
- }, [filteredAnalyticsEvents, chartHeight, svgWidth, t]);
246
+ }, [filteredAnalyticsEvents, chartHeight, svgWidth, liveTick, t]);
235
247
  const selectedBucket = selectedBucketIdx != null ? histogramData.buckets[selectedBucketIdx] : null;
236
248
  return (<react_native_1.View style={styles_1.default.analyticsHeaderCard}>
237
249
  {/* ── 1. Top Header Row (GA4 Style) ─────────────────────────────────── */}
@@ -303,7 +315,7 @@ const AnalyticsHeader = react_1.default.memo(() => {
303
315
  }}/>)}
304
316
  </react_native_1.View>
305
317
 
306
- {/* Multi-Select Category Buttons with Checkboxes */}
318
+ {/* Multi-Select Category Buttons */}
307
319
  <react_native_1.View style={{
308
320
  flexDirection: 'row',
309
321
  flexWrap: 'wrap',
@@ -332,18 +344,6 @@ const AnalyticsHeader = react_1.default.memo(() => {
332
344
  elevation: 2,
333
345
  },
334
346
  ]}>
335
- <react_native_1.View style={{
336
- width: 12,
337
- height: 12,
338
- borderRadius: 3,
339
- borderWidth: 1.2,
340
- borderColor: isAllSelected ? AppColors_1.AppColors.white : AppColors_1.AppColors.indigo400,
341
- backgroundColor: isAllSelected ? AppColors_1.AppColors.white : 'transparent',
342
- alignItems: 'center',
343
- justifyContent: 'center',
344
- }}>
345
- {isAllSelected && <NetworkIcons_1.CheckIcon color={AppColors_1.AppColors.indigo600Alt} size={8}/>}
346
- </react_native_1.View>
347
347
  <NetworkIcons_1.LayersIcon color={isAllSelected ? AppColors_1.AppColors.white : AppColors_1.AppColors.indigo600Alt} size={11}/>
348
348
  <react_native_1.Text style={{
349
349
  fontFamily: AppFonts_1.AppFonts.interBold,
@@ -379,18 +379,6 @@ const AnalyticsHeader = react_1.default.memo(() => {
379
379
  elevation: 2,
380
380
  },
381
381
  ]}>
382
- <react_native_1.View style={{
383
- width: 12,
384
- height: 12,
385
- borderRadius: 3,
386
- borderWidth: 1.2,
387
- borderColor: isSelected ? AppColors_1.AppColors.white : AppColors_1.AppColors.amber500,
388
- backgroundColor: isSelected ? AppColors_1.AppColors.white : 'transparent',
389
- alignItems: 'center',
390
- justifyContent: 'center',
391
- }}>
392
- {isSelected && <NetworkIcons_1.CheckIcon color={AppColors_1.AppColors.amber600} size={8}/>}
393
- </react_native_1.View>
394
382
  <NetworkIcons_1.CartIcon color={isSelected ? AppColors_1.AppColors.white : AppColors_1.AppColors.amber700} size={11}/>
395
383
  <react_native_1.Text style={{
396
384
  fontFamily: AppFonts_1.AppFonts.interBold,
@@ -426,18 +414,6 @@ const AnalyticsHeader = react_1.default.memo(() => {
426
414
  elevation: 2,
427
415
  },
428
416
  ]}>
429
- <react_native_1.View style={{
430
- width: 12,
431
- height: 12,
432
- borderRadius: 3,
433
- borderWidth: 1.2,
434
- borderColor: isSelected ? AppColors_1.AppColors.white : AppColors_1.AppColors.sky400,
435
- backgroundColor: isSelected ? AppColors_1.AppColors.white : 'transparent',
436
- alignItems: 'center',
437
- justifyContent: 'center',
438
- }}>
439
- {isSelected && <NetworkIcons_1.CheckIcon color={AppColors_1.AppColors.sky600} size={8}/>}
440
- </react_native_1.View>
441
417
  <NetworkIcons_1.GlobeIcon color={isSelected ? AppColors_1.AppColors.white : AppColors_1.AppColors.sky600} size={11}/>
442
418
  <react_native_1.Text style={{
443
419
  fontFamily: AppFonts_1.AppFonts.interBold,
@@ -473,18 +449,6 @@ const AnalyticsHeader = react_1.default.memo(() => {
473
449
  elevation: 2,
474
450
  },
475
451
  ]}>
476
- <react_native_1.View style={{
477
- width: 12,
478
- height: 12,
479
- borderRadius: 3,
480
- borderWidth: 1.2,
481
- borderColor: isSelected ? AppColors_1.AppColors.white : AppColors_1.AppColors.purple400,
482
- backgroundColor: isSelected ? AppColors_1.AppColors.white : 'transparent',
483
- alignItems: 'center',
484
- justifyContent: 'center',
485
- }}>
486
- {isSelected && <NetworkIcons_1.CheckIcon color={AppColors_1.AppColors.violet600} size={8}/>}
487
- </react_native_1.View>
488
452
  <NetworkIcons_1.BoltIcon color={isSelected ? AppColors_1.AppColors.white : AppColors_1.AppColors.purple} size={11}/>
489
453
  <react_native_1.Text style={{
490
454
  fontFamily: AppFonts_1.AppFonts.interBold,
@@ -520,18 +484,6 @@ const AnalyticsHeader = react_1.default.memo(() => {
520
484
  elevation: 2,
521
485
  },
522
486
  ]}>
523
- <react_native_1.View style={{
524
- width: 12,
525
- height: 12,
526
- borderRadius: 3,
527
- borderWidth: 1.2,
528
- borderColor: isSelected ? AppColors_1.AppColors.white : AppColors_1.AppColors.pink400,
529
- backgroundColor: isSelected ? AppColors_1.AppColors.white : 'transparent',
530
- alignItems: 'center',
531
- justifyContent: 'center',
532
- }}>
533
- {isSelected && <NetworkIcons_1.CheckIcon color={AppColors_1.AppColors.pink600} size={8}/>}
534
- </react_native_1.View>
535
487
  <NetworkIcons_1.SparkleIcon color={isSelected ? AppColors_1.AppColors.white : AppColors_1.AppColors.brandPurple} size={11}/>
536
488
  <react_native_1.Text style={{
537
489
  fontFamily: AppFonts_1.AppFonts.interBold,
@@ -628,8 +580,8 @@ const AnalyticsHeader = react_1.default.memo(() => {
628
580
  </react_native_1.View>
629
581
 
630
582
  {/* ── Crashlytics-Style Multi-Bar Histogram with Trendline Overlay ── */}
631
- <react_native_1.View style={{ height: chartHeight, position: 'relative' }}>
632
- <react_native_svg_1.default width="100%" height={chartHeight} viewBox={`0 0 ${svgWidth} ${chartHeight}`}>
583
+ <react_native_1.View style={{ height: chartHeight, position: 'relative', overflow: 'hidden', borderRadius: 8 }}>
584
+ <react_native_svg_1.default width="100%" height={chartHeight} viewBox={`0 0 ${svgWidth} ${chartHeight}`} preserveAspectRatio="none">
633
585
  <react_native_svg_1.Defs>
634
586
  <react_native_svg_1.LinearGradient id="crashlyticsBarGrad" x1="0" y1="0" x2="0" y2="1">
635
587
  <react_native_svg_1.Stop offset="0%" stopColor="#8B5CF6" stopOpacity="0.9"/>
@@ -727,7 +679,7 @@ const AnalyticsHeader = react_1.default.memo(() => {
727
679
  </react_native_1.View>
728
680
  </react_native_1.View>)}
729
681
 
730
- {/* Timeline Axis Labels */}
682
+ {/* Timeline Axis Labels (60s Realtime Rolling Stream) */}
731
683
  <react_native_1.View style={{
732
684
  flexDirection: 'row',
733
685
  justifyContent: 'space-between',
@@ -739,21 +691,21 @@ const AnalyticsHeader = react_1.default.memo(() => {
739
691
  fontSize: 8.5,
740
692
  color: AppColors_1.AppColors.grayTextWeak,
741
693
  }}>
742
- {t('analytics.time30mAgo')}
694
+ -60s
743
695
  </react_native_1.Text>
744
696
  <react_native_1.Text style={{
745
697
  fontFamily: AppFonts_1.AppFonts.interMedium,
746
698
  fontSize: 8.5,
747
699
  color: AppColors_1.AppColors.grayTextWeak,
748
700
  }}>
749
- {t('analytics.time20mAgo')}
701
+ -40s
750
702
  </react_native_1.Text>
751
703
  <react_native_1.Text style={{
752
704
  fontFamily: AppFonts_1.AppFonts.interMedium,
753
705
  fontSize: 8.5,
754
706
  color: AppColors_1.AppColors.grayTextWeak,
755
707
  }}>
756
- {t('analytics.time10mAgo')}
708
+ -20s
757
709
  </react_native_1.Text>
758
710
  <react_native_1.Text style={{
759
711
  fontFamily: AppFonts_1.AppFonts.interBold,
@@ -993,7 +945,7 @@ const AnalyticsTab = react_1.default.memo(() => {
993
945
  <AnalyticsFilterModal_1.default visible={isFilterModalOpen} onClose={() => setIsFilterModalOpen(false)}/>
994
946
 
995
947
  <react_native_1.View style={{ flex: 1 }} onLayout={() => setIsAnalyticsLayoutReady(true)}>
996
- {selectedEvent != null ? (<AnalyticsDetail_1.default event={selectedEvent}/>) : isAnalyticsLayoutReady ? (<react_native_1.FlatList data={filteredAnalyticsEvents} keyExtractor={keyExtractor} ListHeaderComponent={AnalyticsHeader} renderItem={renderItem} initialNumToRender={20} maxToRenderPerBatch={20} windowSize={5} removeClippedSubviews={false} ListEmptyComponent={<react_native_1.View style={styles_1.default.emptyContainer}>
948
+ {isAnalyticsLayoutReady ? (<react_native_1.FlatList data={filteredAnalyticsEvents} keyExtractor={keyExtractor} ListHeaderComponent={AnalyticsHeader} renderItem={renderItem} initialNumToRender={12} maxToRenderPerBatch={8} windowSize={5} removeClippedSubviews={true} renderToHardwareTextureAndroid={true} ListEmptyComponent={<react_native_1.View style={styles_1.default.emptyContainer}>
997
949
  <react_native_1.View style={styles_1.default.emptyIconWrap}>
998
950
  <NetworkIcons_1.EmptyRadarIcon color={AppColors_1.AppColors.purple} size={32}/>
999
951
  </react_native_1.View>