react-native-inapp-inspector 1.1.27 → 1.1.29
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.
- package/android/src/main/java/com/inappinspector/NetworkInspectorModule.java +29 -46
- package/dist/commonjs/components/AppHeaderLogo.js +12 -15
- package/dist/commonjs/components/ConsoleLogCard.js +31 -7
- package/dist/commonjs/components/CopyButton.js +15 -1
- package/dist/commonjs/components/DomainHeader.js +56 -28
- package/dist/commonjs/components/ErrorBoundary.d.ts +1 -1
- package/dist/commonjs/components/ErrorBoundary.js +530 -100
- package/dist/commonjs/components/HighlightText.js +7 -1
- package/dist/commonjs/components/Inspector/AnalyticsTab.js +190 -126
- package/dist/commonjs/components/Inspector/BundleTab.d.ts +1 -0
- package/dist/commonjs/components/Inspector/BundleTab.js +145 -21
- package/dist/commonjs/components/Inspector/CrashTab.js +0 -8
- package/dist/commonjs/components/Inspector/InspectorHeader.js +17 -3
- package/dist/commonjs/components/Inspector/LogDetail.js +8 -5
- package/dist/commonjs/components/Inspector/MainScreen.js +4 -0
- package/dist/commonjs/components/Inspector/NetworkDetail.js +65 -24
- package/dist/commonjs/components/Inspector/PerformanceTab.d.ts +5 -0
- package/dist/commonjs/components/Inspector/PerformanceTab.js +588 -155
- package/dist/commonjs/components/Inspector/SettingsPanel.js +57 -22
- package/dist/commonjs/components/Inspector/TabBar.js +13 -1
- package/dist/commonjs/components/JsonViewer.js +25 -3
- package/dist/commonjs/components/LogCard.js +173 -40
- package/dist/commonjs/components/NetworkIcons.d.ts +112 -102
- package/dist/commonjs/components/Toast.d.ts +3 -0
- package/dist/commonjs/components/Toast.js +152 -0
- package/dist/commonjs/components/TouchableScale.d.ts +1 -0
- package/dist/commonjs/components/TouchableScale.js +3 -3
- package/dist/commonjs/components/TreeNode.js +1 -1
- package/dist/commonjs/constants/index.js +6 -6
- package/dist/commonjs/constants/version.d.ts +1 -1
- package/dist/commonjs/constants/version.js +1 -1
- package/dist/commonjs/customHooks/analyticsLogger.d.ts +1 -11
- package/dist/commonjs/customHooks/analyticsLogger.js +8 -1
- package/dist/commonjs/customHooks/bundleAnalyzer.js +121 -124
- package/dist/commonjs/customHooks/networkLogger.d.ts +1 -0
- package/dist/commonjs/customHooks/networkLogger.js +16 -0
- package/dist/commonjs/customHooks/performanceTracker.d.ts +74 -0
- package/dist/commonjs/customHooks/performanceTracker.js +546 -392
- package/dist/commonjs/customHooks/reduxLogger.d.ts +1 -0
- package/dist/commonjs/customHooks/reduxLogger.js +3 -1
- package/dist/commonjs/helpers/index.d.ts +4 -0
- package/dist/commonjs/helpers/index.js +92 -69
- package/dist/commonjs/helpers/toast.d.ts +4 -0
- package/dist/commonjs/helpers/toast.js +20 -0
- package/dist/commonjs/i18n/locales/en.json +229 -5
- package/dist/commonjs/index.d.ts +1 -1
- package/dist/commonjs/index.js +36 -2
- package/dist/commonjs/styles/index.d.ts +63 -15
- package/dist/commonjs/styles/index.js +79 -32
- package/dist/commonjs/types/interfaces.d.ts +3 -0
- package/dist/esm/components/AppHeaderLogo.js +12 -15
- package/dist/esm/components/ConsoleLogCard.js +33 -9
- package/dist/esm/components/CopyButton.js +15 -1
- package/dist/esm/components/DomainHeader.js +56 -28
- package/dist/esm/components/ErrorBoundary.d.ts +1 -1
- package/dist/esm/components/ErrorBoundary.js +498 -101
- package/dist/esm/components/HighlightText.js +7 -1
- package/dist/esm/components/Inspector/AnalyticsTab.js +191 -127
- package/dist/esm/components/Inspector/BundleTab.d.ts +1 -0
- package/dist/esm/components/Inspector/BundleTab.js +145 -23
- package/dist/esm/components/Inspector/CrashTab.js +0 -8
- package/dist/esm/components/Inspector/InspectorHeader.js +18 -4
- package/dist/esm/components/Inspector/LogDetail.js +10 -7
- package/dist/esm/components/Inspector/MainScreen.js +4 -0
- package/dist/esm/components/Inspector/NetworkDetail.js +66 -25
- package/dist/esm/components/Inspector/PerformanceTab.d.ts +5 -0
- package/dist/esm/components/Inspector/PerformanceTab.js +591 -158
- package/dist/esm/components/Inspector/SettingsPanel.js +57 -22
- package/dist/esm/components/Inspector/TabBar.js +13 -1
- package/dist/esm/components/JsonViewer.js +25 -3
- package/dist/esm/components/LogCard.js +175 -42
- package/dist/esm/components/NetworkIcons.d.ts +112 -102
- package/dist/esm/components/Toast.d.ts +3 -0
- package/dist/esm/components/Toast.js +117 -0
- package/dist/esm/components/TouchableScale.d.ts +1 -0
- package/dist/esm/components/TouchableScale.js +3 -3
- package/dist/esm/components/TreeNode.js +1 -1
- package/dist/esm/constants/index.js +6 -6
- package/dist/esm/constants/version.d.ts +1 -1
- package/dist/esm/constants/version.js +1 -1
- package/dist/esm/customHooks/analyticsLogger.d.ts +1 -11
- package/dist/esm/customHooks/analyticsLogger.js +6 -0
- package/dist/esm/customHooks/bundleAnalyzer.js +121 -124
- package/dist/esm/customHooks/networkLogger.d.ts +1 -0
- package/dist/esm/customHooks/networkLogger.js +16 -0
- package/dist/esm/customHooks/performanceTracker.d.ts +74 -0
- package/dist/esm/customHooks/performanceTracker.js +531 -391
- package/dist/esm/customHooks/reduxLogger.d.ts +1 -0
- package/dist/esm/customHooks/reduxLogger.js +1 -0
- package/dist/esm/helpers/index.d.ts +4 -0
- package/dist/esm/helpers/index.js +87 -69
- package/dist/esm/helpers/toast.d.ts +4 -0
- package/dist/esm/helpers/toast.js +15 -0
- package/dist/esm/i18n/locales/en.json +229 -5
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.js +24 -3
- package/dist/esm/styles/index.d.ts +63 -15
- package/dist/esm/styles/index.js +79 -32
- package/dist/esm/types/interfaces.d.ts +3 -0
- package/package.json +4 -1
|
@@ -8,6 +8,12 @@ const react_native_1 = require("react-native");
|
|
|
8
8
|
// Helpers
|
|
9
9
|
const helpers_1 = require("../helpers");
|
|
10
10
|
const HighlightText = react_1.default.memo(function HighlightText({ text, search, style, highlightStyle, detectLinks, numberOfLines, ...rest }) {
|
|
11
|
+
// Optimization: For huge strings (> 20KB) with no active search, bypass all splitting/regex overhead
|
|
12
|
+
if (!text || (text.length > 20000 && !search && !detectLinks)) {
|
|
13
|
+
return (<react_native_1.Text style={style} numberOfLines={numberOfLines} {...rest}>
|
|
14
|
+
{text}
|
|
15
|
+
</react_native_1.Text>);
|
|
16
|
+
}
|
|
11
17
|
// Regex to detect absolute URLs
|
|
12
18
|
const URL_REGEX = /(https?:\/\/[^\s]+)/g;
|
|
13
19
|
const renderNormalOrHighlighted = (subText, keyPrefix) => {
|
|
@@ -22,7 +28,7 @@ const HighlightText = react_1.default.memo(function HighlightText({ text, search
|
|
|
22
28
|
</react_native_1.Text>) : (<react_native_1.Text key={i}>{part}</react_native_1.Text>))}
|
|
23
29
|
</react_native_1.Text>);
|
|
24
30
|
};
|
|
25
|
-
if (detectLinks && text) {
|
|
31
|
+
if (detectLinks && text && text.length < 20000) {
|
|
26
32
|
const parts = text.split(URL_REGEX);
|
|
27
33
|
return (<react_native_1.Text style={style} numberOfLines={numberOfLines} {...rest}>
|
|
28
34
|
{parts.map((part, i) => {
|
|
@@ -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 =
|
|
141
|
-
const
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
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
|
-
|
|
173
|
-
const
|
|
174
|
-
|
|
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
|
-
|
|
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}>
|
|
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 ? '
|
|
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 ?
|
|
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 ? '
|
|
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:
|
|
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
|
-
|
|
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,143 @@ 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
|
-
{/*
|
|
314
|
-
<react_native_1.View style={{
|
|
315
|
-
|
|
340
|
+
{/* ── Crashlytics-Style Multi-Bar Histogram with Trendline Overlay ── */}
|
|
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="crashlyticsBarGrad" x1="0" y1="0" x2="0" y2="1">
|
|
345
|
+
<react_native_svg_1.Stop offset="0%" stopColor="#8B5CF6" stopOpacity="0.9"/>
|
|
346
|
+
<react_native_svg_1.Stop offset="100%" stopColor="#6366F1" stopOpacity="0.6"/>
|
|
347
|
+
</react_native_svg_1.LinearGradient>
|
|
348
|
+
<react_native_svg_1.LinearGradient id="crashlyticsAreaGrad" x1="0" y1="0" x2="0" y2="1">
|
|
349
|
+
<react_native_svg_1.Stop offset="0%" stopColor="#8B5CF6" stopOpacity="0.25"/>
|
|
350
|
+
<react_native_svg_1.Stop offset="80%" stopColor="#8B5CF6" stopOpacity="0.04"/>
|
|
351
|
+
<react_native_svg_1.Stop offset="100%" stopColor="#8B5CF6" stopOpacity="0.0"/>
|
|
352
|
+
</react_native_svg_1.LinearGradient>
|
|
353
|
+
</react_native_svg_1.Defs>
|
|
354
|
+
|
|
355
|
+
{/* Subtle Grid Guidelines */}
|
|
356
|
+
<react_native_svg_1.Line x1="6" y1={chartHeight - 6} x2={svgWidth - 6} y2={chartHeight - 6} stroke="#E2E8F0" strokeWidth="1"/>
|
|
357
|
+
<react_native_svg_1.Line x1="6" y1={chartHeight / 2} x2={svgWidth - 6} y2={chartHeight / 2} stroke="#F1F5F9" strokeWidth="1" strokeDasharray="4,4"/>
|
|
358
|
+
|
|
359
|
+
{/* Glowing Area Underlay */}
|
|
360
|
+
<react_native_svg_1.Path d={histogramData.areaPath} fill="url(#crashlyticsAreaGrad)"/>
|
|
361
|
+
|
|
362
|
+
{/* Vertical Crashlytics Histogram Bars */}
|
|
363
|
+
{histogramData.buckets.map((b, idx) => {
|
|
364
|
+
const isSelected = selectedBucketIdx === idx;
|
|
365
|
+
const barWidth = 10;
|
|
366
|
+
const barX = b.x - barWidth / 2;
|
|
367
|
+
const barHeight = Math.max(3, chartHeight - 8 - b.y);
|
|
368
|
+
const barY = chartHeight - 8 - barHeight;
|
|
369
|
+
return (<react_native_svg_1.G key={`bar-${b.index}`}>
|
|
370
|
+
{/* Background slot */}
|
|
371
|
+
<react_native_svg_1.Rect x={barX} y={6} width={barWidth} height={chartHeight - 14} rx={3} fill={isSelected ? '#EDE9FE' : '#F8FAFC'}/>
|
|
372
|
+
|
|
373
|
+
{/* Active Event Bar */}
|
|
374
|
+
{b.total > 0 && (<react_native_svg_1.Rect x={barX} y={barY} width={barWidth} height={barHeight} rx={3} fill="url(#crashlyticsBarGrad)"/>)}
|
|
375
|
+
|
|
376
|
+
{/* Selected Cursor Line */}
|
|
377
|
+
{isSelected && (<react_native_svg_1.Line x1={b.x} y1={4} x2={b.x} y2={chartHeight - 6} stroke="#8B5CF6" strokeWidth="1.5" strokeDasharray="2,2"/>)}
|
|
378
|
+
</react_native_svg_1.G>);
|
|
379
|
+
})}
|
|
380
|
+
|
|
381
|
+
{/* Crashlytics Apex Trendline */}
|
|
382
|
+
<react_native_svg_1.Path d={histogramData.linePath} fill="none" stroke="#8B5CF6" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
|
|
383
|
+
|
|
384
|
+
{/* Pulsing Dot on Current Active Time Bucket */}
|
|
385
|
+
{histogramData.buckets.length > 0 && (<react_native_svg_1.G>
|
|
386
|
+
<react_native_svg_1.Circle cx={histogramData.buckets[histogramData.buckets.length - 1].x} cy={histogramData.buckets[histogramData.buckets.length - 1].y} r="5.5" fill="#8B5CF6" opacity="0.25"/>
|
|
387
|
+
<react_native_svg_1.Circle cx={histogramData.buckets[histogramData.buckets.length - 1].x} cy={histogramData.buckets[histogramData.buckets.length - 1].y} r="3" fill="#7C3AED"/>
|
|
388
|
+
</react_native_svg_1.G>)}
|
|
389
|
+
</react_native_svg_1.default>
|
|
390
|
+
|
|
391
|
+
{/* Invisible Touch Columns for Interactive Bucket Selection */}
|
|
392
|
+
<react_native_1.View style={{
|
|
393
|
+
position: 'absolute',
|
|
394
|
+
top: 0,
|
|
395
|
+
left: 0,
|
|
396
|
+
right: 0,
|
|
397
|
+
bottom: 0,
|
|
316
398
|
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
399
|
}}>
|
|
324
|
-
|
|
325
|
-
|
|
400
|
+
{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)}/>))}
|
|
401
|
+
</react_native_1.View>
|
|
402
|
+
</react_native_1.View>
|
|
403
|
+
|
|
404
|
+
{/* Selected Bucket Quick Breakdown Overlay */}
|
|
405
|
+
{selectedBucket && (<react_native_1.View style={{
|
|
406
|
+
flexDirection: 'row',
|
|
326
407
|
alignItems: 'center',
|
|
327
|
-
justifyContent: '
|
|
328
|
-
|
|
329
|
-
|
|
408
|
+
justifyContent: 'space-between',
|
|
409
|
+
backgroundColor: AppColors_1.AppColors.white,
|
|
410
|
+
borderRadius: 6,
|
|
411
|
+
paddingHorizontal: 8,
|
|
412
|
+
paddingVertical: 4,
|
|
413
|
+
marginTop: 4,
|
|
414
|
+
borderWidth: 1,
|
|
415
|
+
borderColor: AppColors_1.AppColors.brandPurple,
|
|
330
416
|
}}>
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
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`,
|
|
417
|
+
<react_native_1.Text style={{
|
|
418
|
+
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
419
|
+
fontSize: 10,
|
|
420
|
+
color: AppColors_1.AppColors.primaryBlack,
|
|
351
421
|
}}>
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
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>
|
|
422
|
+
{t('analytics.selectedBucket', {
|
|
423
|
+
time: selectedBucket.ageLabel,
|
|
424
|
+
count: selectedBucket.total,
|
|
425
|
+
})}
|
|
426
|
+
</react_native_1.Text>
|
|
427
|
+
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
|
|
428
|
+
{selectedBucket.ecommerce > 0 && (<react_native_1.Text style={{ fontSize: 9, fontFamily: AppFonts_1.AppFonts.interBold, color: AppColors_1.AppColors.amber700 }}>
|
|
429
|
+
Ecom: {selectedBucket.ecommerce}
|
|
430
|
+
</react_native_1.Text>)}
|
|
431
|
+
{selectedBucket.page_view > 0 && (<react_native_1.Text style={{ fontSize: 9, fontFamily: AppFonts_1.AppFonts.interBold, color: AppColors_1.AppColors.sky500 }}>
|
|
432
|
+
Screen: {selectedBucket.page_view}
|
|
433
|
+
</react_native_1.Text>)}
|
|
434
|
+
{selectedBucket.custom > 0 && (<react_native_1.Text style={{ fontSize: 9, fontFamily: AppFonts_1.AppFonts.interBold, color: AppColors_1.AppColors.brandPurple }}>
|
|
435
|
+
Custom: {selectedBucket.custom}
|
|
436
|
+
</react_native_1.Text>)}
|
|
437
|
+
</react_native_1.View>
|
|
438
|
+
</react_native_1.View>)}
|
|
376
439
|
|
|
377
440
|
{/* Timeline Axis Labels */}
|
|
378
441
|
<react_native_1.View style={{
|
|
379
442
|
flexDirection: 'row',
|
|
380
443
|
justifyContent: 'space-between',
|
|
381
444
|
marginTop: 4,
|
|
382
|
-
paddingHorizontal:
|
|
445
|
+
paddingHorizontal: 4,
|
|
383
446
|
}}>
|
|
384
447
|
<react_native_1.Text style={{
|
|
385
448
|
fontFamily: AppFonts_1.AppFonts.interMedium,
|
|
386
|
-
fontSize: 8,
|
|
449
|
+
fontSize: 8.5,
|
|
387
450
|
color: AppColors_1.AppColors.grayTextWeak,
|
|
388
451
|
}}>
|
|
389
|
-
|
|
452
|
+
{t('analytics.time30mAgo')}
|
|
390
453
|
</react_native_1.Text>
|
|
391
454
|
<react_native_1.Text style={{
|
|
392
455
|
fontFamily: AppFonts_1.AppFonts.interMedium,
|
|
393
|
-
fontSize: 8,
|
|
456
|
+
fontSize: 8.5,
|
|
394
457
|
color: AppColors_1.AppColors.grayTextWeak,
|
|
395
458
|
}}>
|
|
396
|
-
|
|
459
|
+
{t('analytics.time20mAgo')}
|
|
397
460
|
</react_native_1.Text>
|
|
398
461
|
<react_native_1.Text style={{
|
|
399
462
|
fontFamily: AppFonts_1.AppFonts.interMedium,
|
|
400
|
-
fontSize: 8,
|
|
463
|
+
fontSize: 8.5,
|
|
401
464
|
color: AppColors_1.AppColors.grayTextWeak,
|
|
402
465
|
}}>
|
|
403
|
-
|
|
466
|
+
{t('analytics.time10mAgo')}
|
|
404
467
|
</react_native_1.Text>
|
|
405
468
|
<react_native_1.Text style={{
|
|
406
469
|
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
407
|
-
fontSize: 8,
|
|
470
|
+
fontSize: 8.5,
|
|
408
471
|
color: AppColors_1.AppColors.brandPurple,
|
|
409
472
|
}}>
|
|
410
|
-
|
|
473
|
+
{t('analytics.timeNow')}
|
|
411
474
|
</react_native_1.Text>
|
|
412
475
|
</react_native_1.View>
|
|
413
476
|
</react_native_1.View>
|
|
@@ -686,26 +749,26 @@ const AnalyticsHeader = react_1.default.memo(() => {
|
|
|
686
749
|
<react_native_1.View style={styles_1.default.analyticsStatsRow}>
|
|
687
750
|
<react_native_1.View style={styles_1.default.analyticsStatBox}>
|
|
688
751
|
<react_native_1.Text style={styles_1.default.analyticsStatValue}>{totalEvents}</react_native_1.Text>
|
|
689
|
-
<react_native_1.Text style={styles_1.default.analyticsStatLabel}>
|
|
752
|
+
<react_native_1.Text style={styles_1.default.analyticsStatLabel}>{t('analytics.eventCount', { count: totalEvents })}</react_native_1.Text>
|
|
690
753
|
</react_native_1.View>
|
|
691
754
|
<react_native_1.View style={styles_1.default.analyticsStatBox}>
|
|
692
755
|
<react_native_1.Text style={styles_1.default.analyticsStatValue}>
|
|
693
756
|
{Object.keys(userProperties).length}
|
|
694
757
|
</react_native_1.Text>
|
|
695
|
-
<react_native_1.Text style={styles_1.default.analyticsStatLabel}>
|
|
758
|
+
<react_native_1.Text style={styles_1.default.analyticsStatLabel}>{t('analytics.props')}</react_native_1.Text>
|
|
696
759
|
</react_native_1.View>
|
|
697
760
|
<react_native_1.View style={styles_1.default.analyticsStatBox}>
|
|
698
761
|
<react_native_1.Text style={styles_1.default.analyticsStatValue}>
|
|
699
762
|
{Object.keys(defaultParams).length}
|
|
700
763
|
</react_native_1.Text>
|
|
701
|
-
<react_native_1.Text style={styles_1.default.analyticsStatLabel}>
|
|
764
|
+
<react_native_1.Text style={styles_1.default.analyticsStatLabel}>{t('analytics.defaultParameters')}</react_native_1.Text>
|
|
702
765
|
</react_native_1.View>
|
|
703
766
|
</react_native_1.View>
|
|
704
767
|
|
|
705
768
|
{/* Details Section */}
|
|
706
769
|
{(hasUserProps || hasDefaultParams) && (<react_native_1.View style={styles_1.default.analyticsHeaderDetails}>
|
|
707
770
|
{hasUserProps && (<react_native_1.View style={{ marginBottom: 10 }}>
|
|
708
|
-
<react_native_1.Text style={styles_1.default.detailsGroupTitle}>
|
|
771
|
+
<react_native_1.Text style={styles_1.default.detailsGroupTitle}>{t('analytics.userProperties')}</react_native_1.Text>
|
|
709
772
|
{Object.entries(userProperties).map(([k, v]) => (<react_native_1.View key={k} style={styles_1.default.detailsRow}>
|
|
710
773
|
<react_native_1.Text style={styles_1.default.detailsKey} selectable={true}>{k}</react_native_1.Text>
|
|
711
774
|
<react_native_1.Text style={styles_1.default.detailsValue} selectable={true}>{String(v)}</react_native_1.Text>
|
|
@@ -713,7 +776,7 @@ const AnalyticsHeader = react_1.default.memo(() => {
|
|
|
713
776
|
</react_native_1.View>)}
|
|
714
777
|
|
|
715
778
|
{hasDefaultParams && (<react_native_1.View>
|
|
716
|
-
<react_native_1.Text style={styles_1.default.detailsGroupTitle}>
|
|
779
|
+
<react_native_1.Text style={styles_1.default.detailsGroupTitle}>{t('analytics.defaultParameters')}</react_native_1.Text>
|
|
717
780
|
{Object.entries(defaultParams).map(([k, v]) => (<react_native_1.View key={k} style={styles_1.default.detailsRow}>
|
|
718
781
|
<react_native_1.Text style={styles_1.default.detailsKey} selectable={true}>{k}</react_native_1.Text>
|
|
719
782
|
<react_native_1.Text style={styles_1.default.detailsValue} selectable={true}>{String(v)}</react_native_1.Text>
|
|
@@ -724,6 +787,7 @@ const AnalyticsHeader = react_1.default.memo(() => {
|
|
|
724
787
|
</react_native_1.View>);
|
|
725
788
|
});
|
|
726
789
|
const AnalyticsTab = react_1.default.memo(() => {
|
|
790
|
+
const { t } = (0, i18n_1.useTranslation)();
|
|
727
791
|
const { filteredAnalyticsEvents, analyticsSearch, setAnalyticsSearch, handleDelete, selectedEvent, setSelectedEvent, newEventIds, logRouteMapRef, isAnalyticsLayoutReady, setIsAnalyticsLayoutReady, isAnalyticsPaused, setIsAnalyticsPaused, isAnalyticsFilterApplied, } = (0, InspectorContext_1.useInspector)();
|
|
728
792
|
const [isFilterModalOpen, setIsFilterModalOpen] = (0, react_1.useState)(false);
|
|
729
793
|
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;
|