react-native-inapp-inspector 1.1.27 → 1.1.28

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 (65) hide show
  1. package/android/src/main/java/com/inappinspector/NetworkInspectorModule.java +34 -0
  2. package/dist/commonjs/components/ErrorBoundary.d.ts +1 -1
  3. package/dist/commonjs/components/ErrorBoundary.js +530 -100
  4. package/dist/commonjs/components/Inspector/AnalyticsTab.js +176 -126
  5. package/dist/commonjs/components/Inspector/BundleTab.d.ts +1 -0
  6. package/dist/commonjs/components/Inspector/BundleTab.js +145 -21
  7. package/dist/commonjs/components/Inspector/CrashTab.js +0 -8
  8. package/dist/commonjs/components/Inspector/NetworkDetail.js +41 -0
  9. package/dist/commonjs/components/Inspector/PerformanceTab.d.ts +5 -0
  10. package/dist/commonjs/components/Inspector/PerformanceTab.js +588 -155
  11. package/dist/commonjs/components/Inspector/SettingsPanel.js +57 -22
  12. package/dist/commonjs/components/Inspector/TabBar.js +13 -1
  13. package/dist/commonjs/components/LogCard.js +75 -34
  14. package/dist/commonjs/components/NetworkIcons.d.ts +112 -102
  15. package/dist/commonjs/constants/version.d.ts +1 -1
  16. package/dist/commonjs/constants/version.js +1 -1
  17. package/dist/commonjs/customHooks/analyticsLogger.d.ts +1 -11
  18. package/dist/commonjs/customHooks/analyticsLogger.js +8 -1
  19. package/dist/commonjs/customHooks/bundleAnalyzer.js +121 -124
  20. package/dist/commonjs/customHooks/networkLogger.d.ts +1 -0
  21. package/dist/commonjs/customHooks/networkLogger.js +16 -0
  22. package/dist/commonjs/customHooks/performanceTracker.d.ts +74 -0
  23. package/dist/commonjs/customHooks/performanceTracker.js +546 -392
  24. package/dist/commonjs/customHooks/reduxLogger.d.ts +1 -0
  25. package/dist/commonjs/customHooks/reduxLogger.js +3 -1
  26. package/dist/commonjs/helpers/index.js +27 -3
  27. package/dist/commonjs/i18n/locales/en.json +225 -4
  28. package/dist/commonjs/index.d.ts +1 -1
  29. package/dist/commonjs/index.js +36 -2
  30. package/dist/commonjs/styles/index.d.ts +3 -1
  31. package/dist/commonjs/styles/index.js +8 -6
  32. package/dist/commonjs/types/interfaces.d.ts +3 -0
  33. package/dist/esm/components/ErrorBoundary.d.ts +1 -1
  34. package/dist/esm/components/ErrorBoundary.js +498 -101
  35. package/dist/esm/components/Inspector/AnalyticsTab.js +177 -127
  36. package/dist/esm/components/Inspector/BundleTab.d.ts +1 -0
  37. package/dist/esm/components/Inspector/BundleTab.js +145 -23
  38. package/dist/esm/components/Inspector/CrashTab.js +0 -8
  39. package/dist/esm/components/Inspector/NetworkDetail.js +41 -0
  40. package/dist/esm/components/Inspector/PerformanceTab.d.ts +5 -0
  41. package/dist/esm/components/Inspector/PerformanceTab.js +591 -158
  42. package/dist/esm/components/Inspector/SettingsPanel.js +57 -22
  43. package/dist/esm/components/Inspector/TabBar.js +13 -1
  44. package/dist/esm/components/LogCard.js +75 -34
  45. package/dist/esm/components/NetworkIcons.d.ts +112 -102
  46. package/dist/esm/constants/version.d.ts +1 -1
  47. package/dist/esm/constants/version.js +1 -1
  48. package/dist/esm/customHooks/analyticsLogger.d.ts +1 -11
  49. package/dist/esm/customHooks/analyticsLogger.js +6 -0
  50. package/dist/esm/customHooks/bundleAnalyzer.js +121 -124
  51. package/dist/esm/customHooks/networkLogger.d.ts +1 -0
  52. package/dist/esm/customHooks/networkLogger.js +16 -0
  53. package/dist/esm/customHooks/performanceTracker.d.ts +74 -0
  54. package/dist/esm/customHooks/performanceTracker.js +531 -391
  55. package/dist/esm/customHooks/reduxLogger.d.ts +1 -0
  56. package/dist/esm/customHooks/reduxLogger.js +1 -0
  57. package/dist/esm/helpers/index.js +27 -3
  58. package/dist/esm/i18n/locales/en.json +225 -4
  59. package/dist/esm/index.d.ts +1 -1
  60. package/dist/esm/index.js +24 -3
  61. package/dist/esm/styles/index.d.ts +3 -1
  62. package/dist/esm/styles/index.js +8 -6
  63. package/dist/esm/types/interfaces.d.ts +3 -0
  64. package/ios/NetworkInspectorModule.m +10 -0
  65. package/package.json +1 -1
@@ -46,11 +46,14 @@ const EndOfListFooter_1 = __importDefault(require("../EndOfListFooter"));
46
46
  const styles_1 = __importDefault(require("../../styles"));
47
47
  const AppColors_1 = require("../../styles/AppColors");
48
48
  const AppFonts_1 = require("../../styles/AppFonts");
49
+ const i18n_1 = require("../../i18n");
50
+ const react_native_svg_1 = __importStar(require("react-native-svg"));
49
51
  const TouchableScale_1 = __importDefault(require("../TouchableScale"));
50
52
  const analyticsLogger_1 = require("../../customHooks/analyticsLogger");
51
53
  const helpers_1 = require("../../helpers");
52
54
  const NetworkIcons_1 = require("../NetworkIcons");
53
55
  const AnalyticsHeader = react_1.default.memo(() => {
56
+ const { t } = (0, i18n_1.useTranslation)();
54
57
  const { analyticsEvents, filteredAnalyticsEvents, analyticsFilters, setAnalyticsFilters, analyticsHeaderExpanded, setAnalyticsHeaderExpanded, } = (0, InspectorContext_1.useInspector)();
55
58
  const userId = (0, analyticsLogger_1.getCurrentUserId)();
56
59
  const userProperties = (0, analyticsLogger_1.getCurrentUserProperties)();
@@ -135,20 +138,31 @@ const AnalyticsHeader = react_1.default.memo(() => {
135
138
  }
136
139
  });
137
140
  };
138
- // 12-Bucket GA4 Realtime Stacked Histogram Graph (-30m / 30s to NOW)
141
+ // 12-Bucket GA4 Realtime Stacked Histogram & Spline Wave Graph (-30m / 30s to NOW)
139
142
  const BUCKET_COUNT = 12;
140
- const chartHeight = 56;
141
- const histogramBars = (0, react_1.useMemo)(() => {
142
- const buckets = Array.from({ length: BUCKET_COUNT }, () => ({
143
- ecommerce: 0,
144
- page_view: 0,
145
- system: 0,
146
- custom: 0,
147
- total: 0,
148
- }));
143
+ const chartHeight = 64;
144
+ const svgWidth = 320;
145
+ const [selectedBucketIdx, setSelectedBucketIdx] = (0, react_1.useState)(null);
146
+ const histogramData = (0, react_1.useMemo)(() => {
147
+ const buckets = [];
149
148
  const now = Date.now();
150
149
  const windowMs = 60000; // 60s window
151
150
  const bucketDuration = windowMs / BUCKET_COUNT;
151
+ for (let i = 0; i < BUCKET_COUNT; i++) {
152
+ const bucketAgeSec = Math.round(((BUCKET_COUNT - 1 - i) * bucketDuration) / 1000);
153
+ buckets.push({
154
+ index: i,
155
+ ecommerce: 0,
156
+ page_view: 0,
157
+ system: 0,
158
+ custom: 0,
159
+ total: 0,
160
+ x: (i / (BUCKET_COUNT - 1)) * (svgWidth - 24) + 12,
161
+ y: chartHeight - 12,
162
+ isLatest: i === BUCKET_COUNT - 1,
163
+ ageLabel: i === BUCKET_COUNT - 1 ? t('analytics.timeNow') : `-${bucketAgeSec}s`,
164
+ });
165
+ }
152
166
  for (const e of filteredAnalyticsEvents) {
153
167
  const age = now - e.timestamp;
154
168
  if (age >= 0 && age < windowMs) {
@@ -169,30 +183,43 @@ const AnalyticsHeader = react_1.default.memo(() => {
169
183
  }
170
184
  }
171
185
  const maxVal = Math.max(...buckets.map(b => b.total), 4);
172
- return buckets.map((b, idx) => {
173
- const totalH = Math.max((b.total / maxVal) * (chartHeight - 14), b.total > 0 ? 8 : 2.5);
174
- const ecomH = b.total > 0 ? (b.ecommerce / b.total) * totalH : 0;
175
- const screenH = b.total > 0 ? (b.page_view / b.total) * totalH : 0;
176
- const sysH = b.total > 0 ? (b.system / b.total) * totalH : 0;
177
- const custH = b.total > 0 ? (b.custom / b.total) * totalH : totalH;
178
- return {
179
- index: idx,
180
- total: b.total,
181
- totalHeight: totalH,
182
- ecomHeight: ecomH,
183
- screenHeight: screenH,
184
- sysHeight: sysH,
185
- custHeight: custH,
186
- isLatest: idx === BUCKET_COUNT - 1,
187
- };
186
+ buckets.forEach(b => {
187
+ const normalizedH = (b.total / maxVal) * (chartHeight - 22);
188
+ b.y = chartHeight - 10 - normalizedH;
188
189
  });
189
- }, [filteredAnalyticsEvents, chartHeight]);
190
+ // Generate Cubic Bézier Spline paths
191
+ let linePath = `M ${buckets[0].x.toFixed(1)} ${buckets[0].y.toFixed(1)}`;
192
+ for (let i = 0; i < buckets.length - 1; i++) {
193
+ const p0 = buckets[Math.max(0, i - 1)];
194
+ const p1 = buckets[i];
195
+ const p2 = buckets[i + 1];
196
+ const p3 = buckets[Math.min(buckets.length - 1, i + 2)];
197
+ const cp1x = p1.x + (p2.x - p0.x) / 6;
198
+ const cp1y = p1.y + (p2.y - p0.y) / 6;
199
+ const cp2x = p2.x - (p3.x - p1.x) / 6;
200
+ const cp2y = p2.y - (p3.y - p1.y) / 6;
201
+ linePath += ` C ${cp1x.toFixed(1)} ${cp1y.toFixed(1)}, ${cp2x.toFixed(1)} ${cp2y.toFixed(1)}, ${p2.x.toFixed(1)} ${p2.y.toFixed(1)}`;
202
+ }
203
+ const lastB = buckets[buckets.length - 1];
204
+ const firstB = buckets[0];
205
+ const areaPath = `${linePath} L ${lastB.x.toFixed(1)} ${chartHeight - 4} L ${firstB.x.toFixed(1)} ${chartHeight - 4} Z`;
206
+ const peakVal = Math.max(...buckets.map(b => b.total), 0);
207
+ const eventRate = Math.round(buckets.reduce((a, b) => a + b.total, 0));
208
+ return {
209
+ buckets,
210
+ linePath,
211
+ areaPath,
212
+ peakVal,
213
+ eventRate,
214
+ };
215
+ }, [filteredAnalyticsEvents, chartHeight, svgWidth, t]);
216
+ const selectedBucket = selectedBucketIdx != null ? histogramData.buckets[selectedBucketIdx] : null;
190
217
  return (<react_native_1.View style={styles_1.default.analyticsHeaderCard}>
191
218
  {/* ── Top Header Row (GA4 Style) ─────────────────────────────────────── */}
192
219
  <react_native_1.View style={styles_1.default.analyticsHeaderTop}>
193
220
  <react_native_1.View style={{ flex: 1 }}>
194
221
  <react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
195
- <react_native_1.Text style={styles_1.default.analyticsHeaderTitle}>Users in last 30 minutes</react_native_1.Text>
222
+ <react_native_1.Text style={styles_1.default.analyticsHeaderTitle}>{t('analytics.realtimeStream')}</react_native_1.Text>
196
223
  <react_native_1.View style={[
197
224
  styles_1.default.statusDot,
198
225
  {
@@ -210,11 +237,11 @@ const AnalyticsHeader = react_1.default.memo(() => {
210
237
  fontFamily: AppFonts_1.AppFonts.interBold,
211
238
  },
212
239
  ]}>
213
- {isTrackingEnabled ? 'Realtime' : 'Paused'}
240
+ {isTrackingEnabled ? t('performance.live') : t('common.pause')}
214
241
  </react_native_1.Text>
215
242
  </react_native_1.View>
216
243
  <react_native_1.Text style={styles_1.default.analyticsHeaderSubtitle} numberOfLines={1}>
217
- {userId ? `User: ${userId}` : 'Anonymous Session'}
244
+ {userId ? `${t('analytics.userId')}: ${userId}` : t('analytics.emptySubtitle')}
218
245
  </react_native_1.Text>
219
246
  </react_native_1.View>
220
247
 
@@ -223,7 +250,7 @@ const AnalyticsHeader = react_1.default.memo(() => {
223
250
  setAnalyticsHeaderExpanded(!analyticsHeaderExpanded);
224
251
  }}>
225
252
  <react_native_1.Text style={styles_1.default.analyticsHeaderToggleText}>
226
- {analyticsHeaderExpanded ? 'Hide Info' : 'Session Info'}
253
+ {analyticsHeaderExpanded ? t('common.close') : t('analytics.eventDetails')}
227
254
  </react_native_1.Text>
228
255
  </react_native_1.TouchableOpacity>
229
256
  </react_native_1.View>
@@ -243,7 +270,7 @@ const AnalyticsHeader = react_1.default.memo(() => {
243
270
  flexDirection: 'row',
244
271
  justifyContent: 'space-between',
245
272
  alignItems: 'flex-start',
246
- marginBottom: 8,
273
+ marginBottom: 6,
247
274
  }}>
248
275
  <react_native_1.View>
249
276
  <react_native_1.View style={{ flexDirection: 'row', alignItems: 'baseline', gap: 6 }}>
@@ -260,13 +287,33 @@ const AnalyticsHeader = react_1.default.memo(() => {
260
287
  fontSize: 10.5,
261
288
  color: AppColors_1.AppColors.grayTextWeak,
262
289
  }}>
263
- events in window
290
+ {t('analytics.eventsInWindow')}
264
291
  </react_native_1.Text>
265
292
  </react_native_1.View>
266
293
  </react_native_1.View>
267
294
 
268
- {/* Realtime Badges */}
295
+ {/* Realtime Rate Badges */}
269
296
  <react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 5 }}>
297
+ <react_native_1.View style={{
298
+ flexDirection: 'row',
299
+ alignItems: 'center',
300
+ gap: 3,
301
+ backgroundColor: `${AppColors_1.AppColors.purple}14`,
302
+ paddingHorizontal: 6,
303
+ paddingVertical: 2.5,
304
+ borderRadius: 4,
305
+ borderWidth: 1,
306
+ borderColor: `${AppColors_1.AppColors.purple}2E`,
307
+ }}>
308
+ <react_native_1.Text style={{
309
+ fontFamily: AppFonts_1.AppFonts.interBold,
310
+ fontSize: 9.5,
311
+ color: AppColors_1.AppColors.purple,
312
+ }}>
313
+ {t('analytics.eventVelocity', { rate: histogramData.eventRate })}
314
+ </react_native_1.Text>
315
+ </react_native_1.View>
316
+
270
317
  {categoryStats.totalRevenue > 0 && (<react_native_1.View style={{
271
318
  flexDirection: 'row',
272
319
  alignItems: 'center',
@@ -287,127 +334,129 @@ const AnalyticsHeader = react_1.default.memo(() => {
287
334
  ${categoryStats.totalRevenue.toFixed(2)}
288
335
  </react_native_1.Text>
289
336
  </react_native_1.View>)}
290
- <react_native_1.View style={{
291
- flexDirection: 'row',
292
- alignItems: 'center',
293
- gap: 4,
294
- backgroundColor: `${AppColors_1.AppColors.brandPurple}14`,
295
- paddingHorizontal: 6,
296
- paddingVertical: 2.5,
297
- borderRadius: 4,
298
- borderWidth: 1,
299
- borderColor: `${AppColors_1.AppColors.brandPurple}2E`,
300
- }}>
301
- <NetworkIcons_1.TargetGoalIcon color={AppColors_1.AppColors.brandPurple} size={10}/>
302
- <react_native_1.Text style={{
303
- fontFamily: AppFonts_1.AppFonts.interBold,
304
- fontSize: 9.5,
305
- color: AppColors_1.AppColors.brandPurple,
306
- }}>
307
- Live Telemetry
308
- </react_native_1.Text>
309
- </react_native_1.View>
310
337
  </react_native_1.View>
311
338
  </react_native_1.View>
312
339
 
313
- {/* GA4 Stacked Realtime Histogram Bar Graph */}
314
- <react_native_1.View style={{
315
- height: chartHeight,
340
+ {/* ── High Precision SVG Spline Area Graph ── */}
341
+ <react_native_1.View style={{ height: chartHeight, position: 'relative' }}>
342
+ <react_native_svg_1.default width="100%" height={chartHeight} viewBox={`0 0 ${svgWidth} ${chartHeight}`}>
343
+ <react_native_svg_1.Defs>
344
+ <react_native_svg_1.LinearGradient id="telemetryAreaGrad" x1="0" y1="0" x2="0" y2="1">
345
+ <react_native_svg_1.Stop offset="0%" stopColor={AppColors_1.AppColors.brandPurple} stopOpacity="0.4"/>
346
+ <react_native_svg_1.Stop offset="80%" stopColor={AppColors_1.AppColors.brandPurple} stopOpacity="0.05"/>
347
+ <react_native_svg_1.Stop offset="100%" stopColor={AppColors_1.AppColors.brandPurple} stopOpacity="0.0"/>
348
+ </react_native_svg_1.LinearGradient>
349
+ </react_native_svg_1.Defs>
350
+
351
+ {/* Baseline & Grid lines */}
352
+ <react_native_svg_1.Line x1="8" y1={chartHeight - 6} x2={svgWidth - 8} y2={chartHeight - 6} stroke={AppColors_1.AppColors.dividerColor} strokeWidth="1"/>
353
+ <react_native_svg_1.Line x1="8" y1={chartHeight / 2} x2={svgWidth - 8} y2={chartHeight / 2} stroke={AppColors_1.AppColors.dividerColor} strokeWidth="0.8" strokeDasharray="3,3"/>
354
+
355
+ {/* Glowing Area Fill */}
356
+ <react_native_svg_1.Path d={histogramData.areaPath} fill="url(#telemetryAreaGrad)"/>
357
+
358
+ {/* Smooth Spline Wave Stroke */}
359
+ <react_native_svg_1.Path d={histogramData.linePath} fill="none" stroke={AppColors_1.AppColors.brandPurple} strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"/>
360
+
361
+ {/* Data Points & Active Bucket Indicators */}
362
+ {histogramData.buckets.map((b, idx) => {
363
+ const isSelected = selectedBucketIdx === idx;
364
+ return (<react_native_svg_1.G key={b.index}>
365
+ {isSelected && (<react_native_svg_1.Line x1={b.x} y1={4} x2={b.x} y2={chartHeight - 6} stroke={AppColors_1.AppColors.brandPurple} strokeWidth="1.2" strokeDasharray="2,2"/>)}
366
+
367
+ {b.total > 0 && (<react_native_svg_1.Circle cx={b.x} cy={b.y} r={isSelected ? 4.5 : 2.8} fill={isSelected ? AppColors_1.AppColors.brandPurple : AppColors_1.AppColors.white} stroke={AppColors_1.AppColors.brandPurple} strokeWidth={isSelected ? 2 : 1.5}/>)}
368
+
369
+ {b.isLatest && (<react_native_svg_1.G>
370
+ <react_native_svg_1.Circle cx={b.x} cy={b.y} r="6.5" fill={AppColors_1.AppColors.brandPurple} opacity="0.22"/>
371
+ <react_native_svg_1.Circle cx={b.x} cy={b.y} r="3" fill={AppColors_1.AppColors.brandPurple}/>
372
+ </react_native_svg_1.G>)}
373
+ </react_native_svg_1.G>);
374
+ })}
375
+ </react_native_svg_1.default>
376
+
377
+ {/* Invisible Touch Columns for Interactive Bucket Selection */}
378
+ <react_native_1.View style={{
379
+ position: 'absolute',
380
+ top: 0,
381
+ left: 0,
382
+ right: 0,
383
+ bottom: 0,
316
384
  flexDirection: 'row',
317
- alignItems: 'flex-end',
318
- justifyContent: 'space-between',
319
- paddingHorizontal: 2,
320
- paddingBottom: 2,
321
- borderBottomWidth: 1,
322
- borderBottomColor: AppColors_1.AppColors.dividerColor,
323
385
  }}>
324
- {histogramBars.map(bar => (<react_native_1.View key={bar.index} style={{
325
- flex: 1,
386
+ {histogramData.buckets.map((b, idx) => (<react_native_1.TouchableOpacity key={b.index} style={{ flex: 1, height: '100%' }} activeOpacity={0.8} onPress={() => setSelectedBucketIdx(selectedBucketIdx === idx ? null : idx)}/>))}
387
+ </react_native_1.View>
388
+ </react_native_1.View>
389
+
390
+ {/* Selected Bucket Quick Breakdown Overlay */}
391
+ {selectedBucket && (<react_native_1.View style={{
392
+ flexDirection: 'row',
326
393
  alignItems: 'center',
327
- justifyContent: 'flex-end',
328
- height: '100%',
329
- marginHorizontal: 1.5,
394
+ justifyContent: 'space-between',
395
+ backgroundColor: AppColors_1.AppColors.white,
396
+ borderRadius: 6,
397
+ paddingHorizontal: 8,
398
+ paddingVertical: 4,
399
+ marginTop: 4,
400
+ borderWidth: 1,
401
+ borderColor: AppColors_1.AppColors.brandPurple,
330
402
  }}>
331
- {bar.total > 0 && (<react_native_1.Text style={{
332
- fontFamily: AppFonts_1.AppFonts.interBold,
333
- fontSize: 7.5,
334
- color: bar.isLatest
335
- ? AppColors_1.AppColors.brandPurple
336
- : AppColors_1.AppColors.grayTextWeak,
337
- marginBottom: 2,
338
- }}>
339
- {bar.total}
340
- </react_native_1.Text>)}
341
- {/* Stacked Category Segments Column */}
342
- <react_native_1.View style={{
343
- width: '100%',
344
- maxWidth: 15,
345
- height: bar.totalHeight,
346
- borderRadius: 3,
347
- overflow: 'hidden',
348
- backgroundColor: bar.total > 0
349
- ? `${AppColors_1.AppColors.grayBorderSecondary}40`
350
- : `${AppColors_1.AppColors.grayBorderSecondary}40`,
403
+ <react_native_1.Text style={{
404
+ fontFamily: AppFonts_1.AppFonts.interBold,
405
+ fontSize: 10,
406
+ color: AppColors_1.AppColors.primaryBlack,
351
407
  }}>
352
- {bar.total > 0 ? (<>
353
- {bar.ecomHeight > 0 && (<react_native_1.View style={{
354
- height: bar.ecomHeight,
355
- backgroundColor: AppColors_1.AppColors.amber500,
356
- }}/>)}
357
- {bar.screenHeight > 0 && (<react_native_1.View style={{
358
- height: bar.screenHeight,
359
- backgroundColor: AppColors_1.AppColors.sky500,
360
- }}/>)}
361
- {bar.sysHeight > 0 && (<react_native_1.View style={{
362
- height: bar.sysHeight,
363
- backgroundColor: AppColors_1.AppColors.purple,
364
- }}/>)}
365
- {bar.custHeight > 0 && (<react_native_1.View style={{
366
- height: bar.custHeight,
367
- backgroundColor: AppColors_1.AppColors.brandPurple,
368
- }}/>)}
369
- </>) : (<react_native_1.View style={{
370
- height: 2.5,
371
- backgroundColor: `${AppColors_1.AppColors.grayBorderSecondary}80`,
372
- }}/>)}
373
- </react_native_1.View>
374
- </react_native_1.View>))}
375
- </react_native_1.View>
408
+ {t('analytics.selectedBucket', {
409
+ time: selectedBucket.ageLabel,
410
+ count: selectedBucket.total,
411
+ })}
412
+ </react_native_1.Text>
413
+ <react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
414
+ {selectedBucket.ecommerce > 0 && (<react_native_1.Text style={{ fontSize: 9, fontFamily: AppFonts_1.AppFonts.interBold, color: AppColors_1.AppColors.amber700 }}>
415
+ Ecom: {selectedBucket.ecommerce}
416
+ </react_native_1.Text>)}
417
+ {selectedBucket.page_view > 0 && (<react_native_1.Text style={{ fontSize: 9, fontFamily: AppFonts_1.AppFonts.interBold, color: AppColors_1.AppColors.sky500 }}>
418
+ Screen: {selectedBucket.page_view}
419
+ </react_native_1.Text>)}
420
+ {selectedBucket.custom > 0 && (<react_native_1.Text style={{ fontSize: 9, fontFamily: AppFonts_1.AppFonts.interBold, color: AppColors_1.AppColors.brandPurple }}>
421
+ Custom: {selectedBucket.custom}
422
+ </react_native_1.Text>)}
423
+ </react_native_1.View>
424
+ </react_native_1.View>)}
376
425
 
377
426
  {/* Timeline Axis Labels */}
378
427
  <react_native_1.View style={{
379
428
  flexDirection: 'row',
380
429
  justifyContent: 'space-between',
381
430
  marginTop: 4,
382
- paddingHorizontal: 2,
431
+ paddingHorizontal: 4,
383
432
  }}>
384
433
  <react_native_1.Text style={{
385
434
  fontFamily: AppFonts_1.AppFonts.interMedium,
386
- fontSize: 8,
435
+ fontSize: 8.5,
387
436
  color: AppColors_1.AppColors.grayTextWeak,
388
437
  }}>
389
- -30 min
438
+ {t('analytics.time30mAgo')}
390
439
  </react_native_1.Text>
391
440
  <react_native_1.Text style={{
392
441
  fontFamily: AppFonts_1.AppFonts.interMedium,
393
- fontSize: 8,
442
+ fontSize: 8.5,
394
443
  color: AppColors_1.AppColors.grayTextWeak,
395
444
  }}>
396
- -20 min
445
+ {t('analytics.time20mAgo')}
397
446
  </react_native_1.Text>
398
447
  <react_native_1.Text style={{
399
448
  fontFamily: AppFonts_1.AppFonts.interMedium,
400
- fontSize: 8,
449
+ fontSize: 8.5,
401
450
  color: AppColors_1.AppColors.grayTextWeak,
402
451
  }}>
403
- -10 min
452
+ {t('analytics.time10mAgo')}
404
453
  </react_native_1.Text>
405
454
  <react_native_1.Text style={{
406
455
  fontFamily: AppFonts_1.AppFonts.interBold,
407
- fontSize: 8,
456
+ fontSize: 8.5,
408
457
  color: AppColors_1.AppColors.brandPurple,
409
458
  }}>
410
- NOW
459
+ {t('analytics.timeNow')}
411
460
  </react_native_1.Text>
412
461
  </react_native_1.View>
413
462
  </react_native_1.View>
@@ -686,26 +735,26 @@ const AnalyticsHeader = react_1.default.memo(() => {
686
735
  <react_native_1.View style={styles_1.default.analyticsStatsRow}>
687
736
  <react_native_1.View style={styles_1.default.analyticsStatBox}>
688
737
  <react_native_1.Text style={styles_1.default.analyticsStatValue}>{totalEvents}</react_native_1.Text>
689
- <react_native_1.Text style={styles_1.default.analyticsStatLabel}>Events</react_native_1.Text>
738
+ <react_native_1.Text style={styles_1.default.analyticsStatLabel}>{t('analytics.eventCount', { count: totalEvents })}</react_native_1.Text>
690
739
  </react_native_1.View>
691
740
  <react_native_1.View style={styles_1.default.analyticsStatBox}>
692
741
  <react_native_1.Text style={styles_1.default.analyticsStatValue}>
693
742
  {Object.keys(userProperties).length}
694
743
  </react_native_1.Text>
695
- <react_native_1.Text style={styles_1.default.analyticsStatLabel}>User Props</react_native_1.Text>
744
+ <react_native_1.Text style={styles_1.default.analyticsStatLabel}>{t('analytics.props')}</react_native_1.Text>
696
745
  </react_native_1.View>
697
746
  <react_native_1.View style={styles_1.default.analyticsStatBox}>
698
747
  <react_native_1.Text style={styles_1.default.analyticsStatValue}>
699
748
  {Object.keys(defaultParams).length}
700
749
  </react_native_1.Text>
701
- <react_native_1.Text style={styles_1.default.analyticsStatLabel}>Defaults</react_native_1.Text>
750
+ <react_native_1.Text style={styles_1.default.analyticsStatLabel}>{t('analytics.defaultParameters')}</react_native_1.Text>
702
751
  </react_native_1.View>
703
752
  </react_native_1.View>
704
753
 
705
754
  {/* Details Section */}
706
755
  {(hasUserProps || hasDefaultParams) && (<react_native_1.View style={styles_1.default.analyticsHeaderDetails}>
707
756
  {hasUserProps && (<react_native_1.View style={{ marginBottom: 10 }}>
708
- <react_native_1.Text style={styles_1.default.detailsGroupTitle}>Active User Properties</react_native_1.Text>
757
+ <react_native_1.Text style={styles_1.default.detailsGroupTitle}>{t('analytics.userProperties')}</react_native_1.Text>
709
758
  {Object.entries(userProperties).map(([k, v]) => (<react_native_1.View key={k} style={styles_1.default.detailsRow}>
710
759
  <react_native_1.Text style={styles_1.default.detailsKey} selectable={true}>{k}</react_native_1.Text>
711
760
  <react_native_1.Text style={styles_1.default.detailsValue} selectable={true}>{String(v)}</react_native_1.Text>
@@ -713,7 +762,7 @@ const AnalyticsHeader = react_1.default.memo(() => {
713
762
  </react_native_1.View>)}
714
763
 
715
764
  {hasDefaultParams && (<react_native_1.View>
716
- <react_native_1.Text style={styles_1.default.detailsGroupTitle}>Default Event Parameters</react_native_1.Text>
765
+ <react_native_1.Text style={styles_1.default.detailsGroupTitle}>{t('analytics.defaultParameters')}</react_native_1.Text>
717
766
  {Object.entries(defaultParams).map(([k, v]) => (<react_native_1.View key={k} style={styles_1.default.detailsRow}>
718
767
  <react_native_1.Text style={styles_1.default.detailsKey} selectable={true}>{k}</react_native_1.Text>
719
768
  <react_native_1.Text style={styles_1.default.detailsValue} selectable={true}>{String(v)}</react_native_1.Text>
@@ -724,6 +773,7 @@ const AnalyticsHeader = react_1.default.memo(() => {
724
773
  </react_native_1.View>);
725
774
  });
726
775
  const AnalyticsTab = react_1.default.memo(() => {
776
+ const { t } = (0, i18n_1.useTranslation)();
727
777
  const { filteredAnalyticsEvents, analyticsSearch, setAnalyticsSearch, handleDelete, selectedEvent, setSelectedEvent, newEventIds, logRouteMapRef, isAnalyticsLayoutReady, setIsAnalyticsLayoutReady, isAnalyticsPaused, setIsAnalyticsPaused, isAnalyticsFilterApplied, } = (0, InspectorContext_1.useInspector)();
728
778
  const [isFilterModalOpen, setIsFilterModalOpen] = (0, react_1.useState)(false);
729
779
  const keyExtractor = (0, react_1.useCallback)((item, index) => item?.id?.toString() ?? index.toString(), []);
@@ -43,5 +43,6 @@ export interface TreeNode {
43
43
  fileCount: number;
44
44
  children: TreeNode[];
45
45
  }
46
+ export declare const downloadBundleFile: (file: BundleFileItem, scriptURL?: string) => Promise<void>;
46
47
  declare const BundleTab: React.MemoExoticComponent<() => React.JSX.Element>;
47
48
  export default BundleTab;