react-native-inapp-inspector 1.1.24 → 1.1.26
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/build.gradle +36 -0
- package/android/src/main/AndroidManifest.xml +3 -0
- package/android/src/main/java/com/inappinspector/NetworkInspectorModule.java +114 -0
- package/android/src/main/java/com/inappinspector/NetworkInspectorPackage.java +28 -0
- package/dist/commonjs/components/AnalyticsEventCard.js +94 -88
- package/dist/commonjs/components/ConsoleLogCard.js +49 -25
- package/dist/commonjs/components/ErrorBoundary.d.ts +1 -1
- package/dist/commonjs/components/ErrorBoundary.js +9 -145
- package/dist/commonjs/components/Inspector/AnalyticsFilterModal.d.ts +7 -0
- package/dist/commonjs/components/Inspector/AnalyticsFilterModal.js +1002 -0
- package/dist/commonjs/components/Inspector/AnalyticsTab.js +637 -10
- package/dist/commonjs/components/Inspector/BundleTab.d.ts +1 -1
- package/dist/commonjs/components/Inspector/BundleTab.js +826 -406
- package/dist/commonjs/components/Inspector/CrashDetail.d.ts +3 -0
- package/dist/commonjs/components/Inspector/CrashDetail.js +796 -0
- package/dist/commonjs/components/Inspector/CrashFilterModal.d.ts +20 -0
- package/dist/commonjs/components/Inspector/CrashFilterModal.js +597 -0
- package/dist/commonjs/components/Inspector/CrashTab.d.ts +3 -0
- package/dist/commonjs/components/Inspector/CrashTab.js +727 -0
- package/dist/commonjs/components/Inspector/InspectorContext.js +6 -1
- package/dist/commonjs/components/Inspector/InspectorHeader.js +65 -28
- package/dist/commonjs/components/Inspector/LogDetail.js +227 -114
- package/dist/commonjs/components/Inspector/MainScreen.js +13 -4
- package/dist/commonjs/components/Inspector/NetworkDetail.js +131 -81
- package/dist/commonjs/components/Inspector/PerformanceTab.js +20 -10
- package/dist/commonjs/components/Inspector/SettingsPanel.js +90 -1
- package/dist/commonjs/components/Inspector/TabBar.js +15 -3
- package/dist/commonjs/components/NetworkIcons.d.ts +25 -0
- package/dist/commonjs/components/NetworkIcons.js +188 -1
- package/dist/commonjs/components/SegmentedTabs.js +33 -23
- package/dist/commonjs/components/TreeNode.js +13 -12
- package/dist/commonjs/constants/version.d.ts +1 -1
- package/dist/commonjs/constants/version.js +1 -1
- package/dist/commonjs/customHooks/analyticsLogger.js +70 -44
- package/dist/commonjs/customHooks/bundleAnalyzer.d.ts +5 -1
- package/dist/commonjs/customHooks/bundleAnalyzer.js +497 -126
- package/dist/commonjs/customHooks/consoleLogger.d.ts +1 -0
- package/dist/commonjs/customHooks/consoleLogger.js +153 -51
- package/dist/commonjs/customHooks/crashHandler.d.ts +64 -0
- package/dist/commonjs/customHooks/crashHandler.js +681 -0
- package/dist/commonjs/customHooks/networkLogger.js +74 -49
- package/dist/commonjs/customHooks/performanceTracker.d.ts +8 -0
- package/dist/commonjs/customHooks/performanceTracker.js +44 -3
- package/dist/commonjs/decorators/index.d.ts +49 -0
- package/dist/commonjs/decorators/index.js +142 -0
- package/dist/commonjs/helpers/gaAnalyticsRegistry.d.ts +18 -0
- package/dist/commonjs/helpers/gaAnalyticsRegistry.js +174 -0
- package/dist/commonjs/helpers/index.d.ts +7 -4
- package/dist/commonjs/helpers/index.js +102 -64
- package/dist/commonjs/i18n/locales/en.json +182 -4
- package/dist/commonjs/index.d.ts +6 -0
- package/dist/commonjs/index.js +310 -8
- package/dist/commonjs/styles/index.d.ts +4 -1
- package/dist/commonjs/styles/index.js +22 -19
- package/dist/commonjs/types/enums.d.ts +156 -9
- package/dist/commonjs/types/enums.js +139 -2
- package/dist/commonjs/types/interfaces.d.ts +70 -1
- package/dist/esm/components/AnalyticsEventCard.js +95 -89
- package/dist/esm/components/ConsoleLogCard.js +49 -25
- package/dist/esm/components/ErrorBoundary.d.ts +1 -1
- package/dist/esm/components/ErrorBoundary.js +10 -113
- package/dist/esm/components/Inspector/AnalyticsFilterModal.d.ts +7 -0
- package/dist/esm/components/Inspector/AnalyticsFilterModal.js +964 -0
- package/dist/esm/components/Inspector/AnalyticsTab.js +639 -12
- package/dist/esm/components/Inspector/BundleTab.d.ts +1 -1
- package/dist/esm/components/Inspector/BundleTab.js +827 -407
- package/dist/esm/components/Inspector/CrashDetail.d.ts +3 -0
- package/dist/esm/components/Inspector/CrashDetail.js +758 -0
- package/dist/esm/components/Inspector/CrashFilterModal.d.ts +20 -0
- package/dist/esm/components/Inspector/CrashFilterModal.js +557 -0
- package/dist/esm/components/Inspector/CrashTab.d.ts +3 -0
- package/dist/esm/components/Inspector/CrashTab.js +689 -0
- package/dist/esm/components/Inspector/InspectorContext.js +1 -0
- package/dist/esm/components/Inspector/InspectorHeader.js +66 -29
- package/dist/esm/components/Inspector/LogDetail.js +227 -114
- package/dist/esm/components/Inspector/MainScreen.js +14 -5
- package/dist/esm/components/Inspector/NetworkDetail.js +132 -49
- package/dist/esm/components/Inspector/PerformanceTab.js +20 -10
- package/dist/esm/components/Inspector/SettingsPanel.js +91 -2
- package/dist/esm/components/Inspector/TabBar.js +16 -4
- package/dist/esm/components/NetworkIcons.d.ts +25 -0
- package/dist/esm/components/NetworkIcons.js +161 -0
- package/dist/esm/components/SegmentedTabs.js +33 -23
- package/dist/esm/components/TreeNode.js +13 -12
- package/dist/esm/constants/version.d.ts +1 -1
- package/dist/esm/constants/version.js +1 -1
- package/dist/esm/customHooks/analyticsLogger.js +70 -44
- package/dist/esm/customHooks/bundleAnalyzer.d.ts +5 -1
- package/dist/esm/customHooks/bundleAnalyzer.js +493 -125
- package/dist/esm/customHooks/consoleLogger.d.ts +1 -0
- package/dist/esm/customHooks/consoleLogger.js +151 -50
- package/dist/esm/customHooks/crashHandler.d.ts +64 -0
- package/dist/esm/customHooks/crashHandler.js +659 -0
- package/dist/esm/customHooks/networkLogger.js +74 -49
- package/dist/esm/customHooks/performanceTracker.d.ts +8 -0
- package/dist/esm/customHooks/performanceTracker.js +38 -1
- package/dist/esm/decorators/index.d.ts +49 -0
- package/dist/esm/decorators/index.js +137 -0
- package/dist/esm/helpers/gaAnalyticsRegistry.d.ts +18 -0
- package/dist/esm/helpers/gaAnalyticsRegistry.js +169 -0
- package/dist/esm/helpers/index.d.ts +7 -4
- package/dist/esm/helpers/index.js +100 -63
- package/dist/esm/i18n/locales/en.json +182 -4
- package/dist/esm/index.d.ts +6 -0
- package/dist/esm/index.js +262 -8
- package/dist/esm/styles/index.d.ts +4 -1
- package/dist/esm/styles/index.js +22 -19
- package/dist/esm/types/enums.d.ts +156 -9
- package/dist/esm/types/enums.js +138 -3
- package/dist/esm/types/interfaces.d.ts +70 -1
- package/ios/NetworkInspectorModule.h +6 -0
- package/ios/NetworkInspectorModule.m +125 -0
- package/package.json +5 -2
- package/react-native-inapp-inspector.podspec +18 -0
|
@@ -6,7 +6,7 @@ import { formatGap, formatTime, getEventColor, getEventCategory, getCategoryColo
|
|
|
6
6
|
import { useTranslation } from '../i18n';
|
|
7
7
|
import HighlightText from './HighlightText';
|
|
8
8
|
import TouchableScale from './TouchableScale';
|
|
9
|
-
import { CartIcon, MoneyIcon } from './NetworkIcons';
|
|
9
|
+
import { CartIcon, MoneyIcon, GlobeIcon, BoltIcon, SparkleIcon, ClockIcon, } from './NetworkIcons';
|
|
10
10
|
// ─── Component ────────────────────────────────────────────────────────────────
|
|
11
11
|
const AnalyticsEventCard = React.memo(function AnalyticsEventCard({ event, onPress, isNew = false, searchStr = '', msSincePrev, computedScreenName, }) {
|
|
12
12
|
const { t } = useTranslation();
|
|
@@ -15,6 +15,8 @@ const AnalyticsEventCard = React.memo(function AnalyticsEventCard({ event, onPre
|
|
|
15
15
|
const userPropCount = event.userProperties
|
|
16
16
|
? Object.keys(event.userProperties).length
|
|
17
17
|
: 0;
|
|
18
|
+
const catKey = getEventCategory(event.name);
|
|
19
|
+
const tagColors = getCategoryColors(catKey);
|
|
18
20
|
// Flash animation for newly logged events
|
|
19
21
|
const flashOpacity = useRef(new Animated.Value(isNew ? 1 : 0)).current;
|
|
20
22
|
useEffect(() => {
|
|
@@ -27,20 +29,29 @@ const AnalyticsEventCard = React.memo(function AnalyticsEventCard({ event, onPre
|
|
|
27
29
|
}
|
|
28
30
|
}, [isNew]);
|
|
29
31
|
const showGap = msSincePrev != null && msSincePrev >= 2000;
|
|
32
|
+
const categoryLabel = catKey === 'page_view'
|
|
33
|
+
? t('analytics.pageViewCategory')
|
|
34
|
+
: catKey === 'ecommerce'
|
|
35
|
+
? t('analytics.ecommerceCategory')
|
|
36
|
+
: catKey === 'system'
|
|
37
|
+
? t('analytics.systemCategory')
|
|
38
|
+
: t('analytics.customCategory');
|
|
30
39
|
return (<View style={cardStyles.container}>
|
|
31
40
|
{/* ── Gap Indicator ─────────────────────────────────────────────────── */}
|
|
32
41
|
{showGap && (<View style={cardStyles.gapContainer}>
|
|
42
|
+
<View style={cardStyles.gapLine}/>
|
|
33
43
|
<Text style={[cardStyles.gapText, { color: AppColors.grayTextWeak }]}>
|
|
34
|
-
{formatGap(msSincePrev)}
|
|
44
|
+
+{formatGap(msSincePrev)}
|
|
35
45
|
</Text>
|
|
46
|
+
<View style={cardStyles.gapLine}/>
|
|
36
47
|
</View>)}
|
|
37
48
|
|
|
38
49
|
{/* ── Main Card ─────────────────────────────────────────────────────── */}
|
|
39
50
|
<TouchableScale onPress={onPress} style={[
|
|
40
51
|
cardStyles.modernCard,
|
|
41
52
|
{
|
|
42
|
-
|
|
43
|
-
|
|
53
|
+
borderLeftWidth: 3.5,
|
|
54
|
+
borderLeftColor: tagColors.text,
|
|
44
55
|
},
|
|
45
56
|
]}>
|
|
46
57
|
<Animated.View style={[
|
|
@@ -54,37 +65,32 @@ const AnalyticsEventCard = React.memo(function AnalyticsEventCard({ event, onPre
|
|
|
54
65
|
},
|
|
55
66
|
]}/>
|
|
56
67
|
|
|
57
|
-
{/* Top Row: Event Name & Timestamp */}
|
|
68
|
+
{/* Top Row: Icon Badge, Event Name, Category Badge & Timestamp */}
|
|
58
69
|
<View style={cardStyles.cardHeader}>
|
|
59
|
-
<View style={{ flexDirection: 'row', alignItems: 'center', gap:
|
|
70
|
+
<View style={{ flexDirection: 'row', alignItems: 'center', gap: 7, flex: 1 }}>
|
|
71
|
+
{/* Category Icon Badge */}
|
|
60
72
|
<View style={[
|
|
61
|
-
cardStyles.
|
|
62
|
-
{ backgroundColor:
|
|
73
|
+
cardStyles.iconBadge,
|
|
74
|
+
{ backgroundColor: tagColors.bg, borderColor: tagColors.border },
|
|
63
75
|
]}>
|
|
64
|
-
<
|
|
76
|
+
{catKey === 'ecommerce' ? (<CartIcon color={tagColors.text} size={12}/>) : catKey === 'page_view' ? (<GlobeIcon color={tagColors.text} size={12}/>) : catKey === 'system' ? (<BoltIcon color={tagColors.text} size={12}/>) : (<SparkleIcon color={tagColors.text} size={12}/>)}
|
|
65
77
|
</View>
|
|
66
78
|
|
|
67
|
-
{
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
{ backgroundColor: tagColors.bg, borderColor: tagColors.border },
|
|
80
|
-
]}>
|
|
81
|
-
<Text style={[cardStyles.categoryText, { color: tagColors.text }]}>
|
|
82
|
-
{categoryLabel}
|
|
83
|
-
</Text>
|
|
84
|
-
</View>);
|
|
85
|
-
})()}
|
|
79
|
+
{/* Event Name */}
|
|
80
|
+
<HighlightText text={event.name} search={searchStr} style={[cardStyles.eventName, { color: AppColors.primaryBlack }]} highlightStyle={cardStyles.highlight} numberOfLines={1}/>
|
|
81
|
+
|
|
82
|
+
{/* Category Pill Tag */}
|
|
83
|
+
<View style={[
|
|
84
|
+
cardStyles.categoryBadge,
|
|
85
|
+
{ backgroundColor: tagColors.bg, borderColor: tagColors.border },
|
|
86
|
+
]}>
|
|
87
|
+
<Text style={[cardStyles.categoryText, { color: tagColors.text }]}>
|
|
88
|
+
{categoryLabel}
|
|
89
|
+
</Text>
|
|
90
|
+
</View>
|
|
86
91
|
|
|
87
|
-
{
|
|
92
|
+
{/* Duplicate Multiplier */}
|
|
93
|
+
{event.count !== undefined && event.count > 0 ? (<View style={[
|
|
88
94
|
cardStyles.duplicateBadge,
|
|
89
95
|
event.count === 1 && {
|
|
90
96
|
backgroundColor: AppColors.grayBackground,
|
|
@@ -96,16 +102,20 @@ const AnalyticsEventCard = React.memo(function AnalyticsEventCard({ event, onPre
|
|
|
96
102
|
event.count === 1 && { color: AppColors.grayTextStrong },
|
|
97
103
|
]}>
|
|
98
104
|
{event.count}×
|
|
99
|
-
{event.count > 1 ? ` ${t('analytics.duplicate')}` : ''}
|
|
100
105
|
</Text>
|
|
101
106
|
</View>) : null}
|
|
102
107
|
</View>
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
108
|
+
|
|
109
|
+
{/* Timestamp */}
|
|
110
|
+
<View style={{ flexDirection: 'row', alignItems: 'center', gap: 3 }}>
|
|
111
|
+
<ClockIcon color={AppColors.grayTextWeak} size={10}/>
|
|
112
|
+
<Text style={[cardStyles.timestamp, { color: AppColors.grayTextWeak }]}>
|
|
113
|
+
{formatTime(event.timestamp)}
|
|
114
|
+
</Text>
|
|
115
|
+
</View>
|
|
106
116
|
</View>
|
|
107
117
|
|
|
108
|
-
{/* Bottom Row: Metadata Chips
|
|
118
|
+
{/* Bottom Row: Metadata Chips (Screen, Params, Value) */}
|
|
109
119
|
<View style={cardStyles.cardBody}>
|
|
110
120
|
<View style={cardStyles.chipsRow}>
|
|
111
121
|
{(() => {
|
|
@@ -122,12 +132,12 @@ const AnalyticsEventCard = React.memo(function AnalyticsEventCard({ event, onPre
|
|
|
122
132
|
return (<View style={[
|
|
123
133
|
cardStyles.chip,
|
|
124
134
|
{
|
|
125
|
-
backgroundColor: AppColors.
|
|
126
|
-
borderColor: AppColors.
|
|
135
|
+
backgroundColor: `${AppColors.amber500}12`,
|
|
136
|
+
borderColor: `${AppColors.amber500}2E`,
|
|
127
137
|
},
|
|
128
138
|
]}>
|
|
129
|
-
<View style={[cardStyles.screenDot, { backgroundColor:
|
|
130
|
-
<Text style={[cardStyles.chipText, { color: AppColors.
|
|
139
|
+
<View style={[cardStyles.screenDot, { backgroundColor: AppColors.amber500 }]}/>
|
|
140
|
+
<Text style={[cardStyles.chipText, { color: AppColors.amber700, fontFamily: AppFonts.interBold }]} numberOfLines={1}>
|
|
131
141
|
{screenNameStr}
|
|
132
142
|
</Text>
|
|
133
143
|
</View>);
|
|
@@ -148,11 +158,11 @@ const AnalyticsEventCard = React.memo(function AnalyticsEventCard({ event, onPre
|
|
|
148
158
|
{userPropCount > 0 && (<View style={[
|
|
149
159
|
cardStyles.chip,
|
|
150
160
|
{
|
|
151
|
-
backgroundColor: AppColors.
|
|
152
|
-
borderColor: AppColors.
|
|
161
|
+
backgroundColor: `${AppColors.brandPurple}10`,
|
|
162
|
+
borderColor: `${AppColors.brandPurple}25`,
|
|
153
163
|
},
|
|
154
164
|
]}>
|
|
155
|
-
<Text style={[cardStyles.chipText, { color: AppColors.
|
|
165
|
+
<Text style={[cardStyles.chipText, { color: AppColors.brandPurple, fontFamily: AppFonts.interBold }]}>
|
|
156
166
|
★ {userPropCount} {t('analytics.props')}
|
|
157
167
|
</Text>
|
|
158
168
|
</View>)}
|
|
@@ -167,7 +177,7 @@ const AnalyticsEventCard = React.memo(function AnalyticsEventCard({ event, onPre
|
|
|
167
177
|
borderColor: AppColors.amberBorder,
|
|
168
178
|
},
|
|
169
179
|
]}>
|
|
170
|
-
<CartIcon color={AppColors.amber700} size={
|
|
180
|
+
<CartIcon color={AppColors.amber700} size={11}/>
|
|
171
181
|
<Text style={[
|
|
172
182
|
cardStyles.chipText,
|
|
173
183
|
{
|
|
@@ -189,18 +199,18 @@ const AnalyticsEventCard = React.memo(function AnalyticsEventCard({ event, onPre
|
|
|
189
199
|
const val = event.params?.value ?? event.params?.price;
|
|
190
200
|
const currency = event.params?.currency ?? '';
|
|
191
201
|
const isPrimitive = typeof val === 'string' || typeof val === 'number';
|
|
192
|
-
if (isPrimitive) {
|
|
193
|
-
const currencyStr = typeof currency === 'string'
|
|
194
|
-
?
|
|
202
|
+
if (val != null && isPrimitive && String(val).trim() !== '') {
|
|
203
|
+
const currencyStr = typeof currency === 'string' && currency.trim() !== ''
|
|
204
|
+
? currency.toUpperCase()
|
|
195
205
|
: '';
|
|
196
206
|
return (<View style={[
|
|
197
207
|
cardStyles.chip,
|
|
198
208
|
{
|
|
199
|
-
backgroundColor: AppColors.
|
|
200
|
-
borderColor: AppColors.
|
|
209
|
+
backgroundColor: `${AppColors.emerald500}15`,
|
|
210
|
+
borderColor: `${AppColors.emerald500}35`,
|
|
201
211
|
},
|
|
202
212
|
]}>
|
|
203
|
-
<MoneyIcon color={AppColors.emerald600} size={
|
|
213
|
+
<MoneyIcon color={AppColors.emerald600} size={11}/>
|
|
204
214
|
<Text style={[
|
|
205
215
|
cardStyles.chipText,
|
|
206
216
|
{
|
|
@@ -222,52 +232,63 @@ const AnalyticsEventCard = React.memo(function AnalyticsEventCard({ event, onPre
|
|
|
222
232
|
// ─── Styles ───────────────────────────────────────────────────────────────────
|
|
223
233
|
const cardStyles = StyleSheet.create({
|
|
224
234
|
container: {
|
|
225
|
-
paddingHorizontal:
|
|
235
|
+
paddingHorizontal: 10,
|
|
226
236
|
paddingVertical: 3,
|
|
227
237
|
},
|
|
228
238
|
gapContainer: {
|
|
239
|
+
flexDirection: 'row',
|
|
229
240
|
alignItems: 'center',
|
|
230
|
-
|
|
241
|
+
justifyContent: 'center',
|
|
242
|
+
marginVertical: 6,
|
|
243
|
+
gap: 8,
|
|
244
|
+
},
|
|
245
|
+
gapLine: {
|
|
246
|
+
flex: 1,
|
|
247
|
+
height: 1,
|
|
248
|
+
backgroundColor: `${AppColors.dividerColor}`,
|
|
231
249
|
},
|
|
232
250
|
gapText: {
|
|
233
|
-
fontFamily: AppFonts.
|
|
234
|
-
fontSize:
|
|
251
|
+
fontFamily: AppFonts.interBold,
|
|
252
|
+
fontSize: 9.5,
|
|
235
253
|
color: AppColors.grayTextWeak,
|
|
236
254
|
letterSpacing: 0.5,
|
|
237
255
|
},
|
|
238
256
|
modernCard: {
|
|
239
257
|
backgroundColor: AppColors.white,
|
|
240
|
-
borderRadius:
|
|
258
|
+
borderRadius: 10,
|
|
241
259
|
borderWidth: 1,
|
|
242
260
|
borderColor: AppColors.dividerColor,
|
|
243
|
-
padding:
|
|
261
|
+
padding: 10,
|
|
244
262
|
shadowColor: AppColors.black,
|
|
245
263
|
shadowOpacity: 0.03,
|
|
246
264
|
shadowRadius: 3,
|
|
247
265
|
shadowOffset: { width: 0, height: 1 },
|
|
248
266
|
elevation: 1,
|
|
249
267
|
overflow: 'hidden',
|
|
268
|
+
gap: 8,
|
|
250
269
|
},
|
|
251
270
|
cardHeader: {
|
|
252
271
|
flexDirection: 'row',
|
|
253
272
|
justifyContent: 'space-between',
|
|
254
273
|
alignItems: 'center',
|
|
255
|
-
marginBottom: 6,
|
|
256
274
|
},
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
275
|
+
iconBadge: {
|
|
276
|
+
width: 22,
|
|
277
|
+
height: 22,
|
|
260
278
|
borderRadius: 6,
|
|
261
279
|
borderWidth: 1,
|
|
280
|
+
alignItems: 'center',
|
|
281
|
+
justifyContent: 'center',
|
|
262
282
|
},
|
|
263
283
|
eventName: {
|
|
264
284
|
fontFamily: AppFonts.interBold,
|
|
265
|
-
fontSize:
|
|
266
|
-
letterSpacing: 0.
|
|
285
|
+
fontSize: 13,
|
|
286
|
+
letterSpacing: 0.1,
|
|
287
|
+
color: AppColors.primaryBlack,
|
|
267
288
|
},
|
|
268
289
|
timestamp: {
|
|
269
290
|
fontFamily: AppFonts.interMedium,
|
|
270
|
-
fontSize:
|
|
291
|
+
fontSize: 10,
|
|
271
292
|
color: AppColors.grayTextWeak,
|
|
272
293
|
},
|
|
273
294
|
highlight: {
|
|
@@ -277,25 +298,24 @@ const cardStyles = StyleSheet.create({
|
|
|
277
298
|
},
|
|
278
299
|
cardBody: {
|
|
279
300
|
flexDirection: 'row',
|
|
280
|
-
alignItems: '
|
|
301
|
+
alignItems: 'center',
|
|
281
302
|
justifyContent: 'space-between',
|
|
282
303
|
},
|
|
283
304
|
chipsRow: {
|
|
284
305
|
flexDirection: 'row',
|
|
285
306
|
alignItems: 'center',
|
|
286
307
|
flexWrap: 'wrap',
|
|
287
|
-
gap:
|
|
308
|
+
gap: 6,
|
|
288
309
|
flex: 1,
|
|
289
310
|
},
|
|
290
311
|
chip: {
|
|
291
312
|
flexDirection: 'row',
|
|
292
313
|
alignItems: 'center',
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
borderRadius: 4,
|
|
314
|
+
paddingHorizontal: 6,
|
|
315
|
+
paddingVertical: 2.5,
|
|
316
|
+
borderRadius: 5,
|
|
297
317
|
borderWidth: 1,
|
|
298
|
-
|
|
318
|
+
gap: 3.5,
|
|
299
319
|
},
|
|
300
320
|
chipText: {
|
|
301
321
|
fontFamily: AppFonts.interMedium,
|
|
@@ -303,17 +323,16 @@ const cardStyles = StyleSheet.create({
|
|
|
303
323
|
color: AppColors.grayText,
|
|
304
324
|
},
|
|
305
325
|
screenDot: {
|
|
306
|
-
width:
|
|
307
|
-
height:
|
|
308
|
-
borderRadius:
|
|
309
|
-
marginRight: 4,
|
|
326
|
+
width: 5,
|
|
327
|
+
height: 5,
|
|
328
|
+
borderRadius: 2.5,
|
|
310
329
|
},
|
|
311
330
|
duplicateBadge: {
|
|
312
331
|
backgroundColor: AppColors.roseBg,
|
|
313
332
|
borderColor: AppColors.roseBorder,
|
|
314
333
|
borderWidth: 1,
|
|
315
334
|
paddingHorizontal: 5,
|
|
316
|
-
paddingVertical:
|
|
335
|
+
paddingVertical: 1.5,
|
|
317
336
|
borderRadius: 4,
|
|
318
337
|
},
|
|
319
338
|
duplicateText: {
|
|
@@ -321,31 +340,18 @@ const cardStyles = StyleSheet.create({
|
|
|
321
340
|
fontSize: 9,
|
|
322
341
|
color: AppColors.rose600,
|
|
323
342
|
textTransform: 'uppercase',
|
|
324
|
-
letterSpacing: 0.5,
|
|
325
343
|
},
|
|
326
344
|
categoryBadge: {
|
|
327
345
|
borderWidth: 1,
|
|
328
346
|
paddingHorizontal: 5,
|
|
329
|
-
paddingVertical:
|
|
347
|
+
paddingVertical: 1.5,
|
|
330
348
|
borderRadius: 4,
|
|
331
349
|
},
|
|
332
350
|
categoryText: {
|
|
333
351
|
fontFamily: AppFonts.interBold,
|
|
334
|
-
fontSize:
|
|
352
|
+
fontSize: 8.5,
|
|
335
353
|
textTransform: 'uppercase',
|
|
336
|
-
letterSpacing: 0.
|
|
337
|
-
},
|
|
338
|
-
miniGraphWrapper: {
|
|
339
|
-
flexDirection: 'row',
|
|
340
|
-
alignItems: 'flex-end',
|
|
341
|
-
height: 18,
|
|
342
|
-
gap: 2,
|
|
343
|
-
marginLeft: 12,
|
|
344
|
-
},
|
|
345
|
-
miniGraphBar: {
|
|
346
|
-
width: 4,
|
|
347
|
-
borderRadius: 2,
|
|
348
|
-
opacity: 0.7,
|
|
354
|
+
letterSpacing: 0.4,
|
|
349
355
|
},
|
|
350
356
|
});
|
|
351
357
|
export default AnalyticsEventCard;
|
|
@@ -17,36 +17,57 @@ const getLogMessageWithBadges = (message, searchStr, textStyle, highlightStyle,
|
|
|
17
17
|
const fullPrefix = match[1];
|
|
18
18
|
const remainingText = message.substring(fullPrefix.length);
|
|
19
19
|
const tags = fullPrefix.match(/\[[^\]]+\]/g) || [];
|
|
20
|
-
const
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
if (
|
|
26
|
-
return
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
if (
|
|
32
|
-
return
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
20
|
+
const getTagDecorator = (tag) => {
|
|
21
|
+
const clean = tag.replace(/[\[\]]/g, '').trim().toUpperCase();
|
|
22
|
+
if (clean === 'AXIOS') {
|
|
23
|
+
return { color: '#059669', icon: '⚡', label: 'AXIOS' };
|
|
24
|
+
}
|
|
25
|
+
if (clean === 'API' || clean === 'FETCH' || clean === 'HTTP' || clean === 'NETWORK') {
|
|
26
|
+
return { color: '#0284C7', icon: '🌐', label: clean };
|
|
27
|
+
}
|
|
28
|
+
if (clean === 'SAMPLE' || clean === 'BATCH') {
|
|
29
|
+
return { color: '#4F46E5', icon: '🎲', label: clean };
|
|
30
|
+
}
|
|
31
|
+
if (clean === 'REDUX' || clean === 'STORE' || clean === 'STATE') {
|
|
32
|
+
return { color: '#7C3AED', icon: '⚛️', label: clean };
|
|
33
|
+
}
|
|
34
|
+
if (clean === 'ANALYTICS' || clean === 'FIREBASE' || clean === 'GA4' || clean === 'GA') {
|
|
35
|
+
return { color: '#0D9488', icon: '📊', label: clean };
|
|
36
|
+
}
|
|
37
|
+
if (clean === 'AUTH' || clean === 'TOKEN' || clean === 'SESSION') {
|
|
38
|
+
return { color: '#D97706', icon: '🔑', label: clean };
|
|
39
|
+
}
|
|
40
|
+
if (clean === 'APP') {
|
|
41
|
+
return { color: '#4F46E5', icon: '📱', label: 'APP' };
|
|
42
|
+
}
|
|
43
|
+
if (clean === 'TEST') {
|
|
44
|
+
return { color: '#10B981', icon: '🧪', label: 'TEST' };
|
|
45
|
+
}
|
|
46
|
+
if (clean === 'WARN' || clean === 'WARNING') {
|
|
47
|
+
return { color: '#D97706', icon: '⚠️', label: 'WARN' };
|
|
48
|
+
}
|
|
49
|
+
if (clean === 'ERROR' || clean === 'CRASH' || clean === 'BUG') {
|
|
50
|
+
return { color: '#DC2626', icon: '💥', label: 'ERROR' };
|
|
51
|
+
}
|
|
52
|
+
if (clean === 'PERF' || clean === 'RENDER') {
|
|
53
|
+
return { color: '#8B5CF6', icon: '⚡', label: clean };
|
|
54
|
+
}
|
|
55
|
+
return { color: AppColors.slate600, icon: '🏷️', label: clean };
|
|
36
56
|
};
|
|
37
57
|
return (<View style={{ flexDirection: 'column', gap: 6 }}>
|
|
38
|
-
<View style={{ flexDirection: 'row', flexWrap: 'wrap', gap:
|
|
58
|
+
<View style={{ flexDirection: 'row', flexWrap: 'wrap', gap: 5 }}>
|
|
39
59
|
{tags.map((tag, i) => {
|
|
40
|
-
const
|
|
60
|
+
const dec = getTagDecorator(tag);
|
|
41
61
|
return (<View key={i} style={[
|
|
42
62
|
styles.prefixTag,
|
|
43
63
|
{
|
|
44
|
-
backgroundColor: `${color}15`,
|
|
45
|
-
borderColor: `${color}35`,
|
|
64
|
+
backgroundColor: `${dec.color}15`,
|
|
65
|
+
borderColor: `${dec.color}35`,
|
|
46
66
|
},
|
|
47
67
|
]}>
|
|
48
|
-
<Text style={
|
|
49
|
-
|
|
68
|
+
<Text style={{ fontSize: 9.5 }}>{dec.icon}</Text>
|
|
69
|
+
<Text style={[styles.prefixTagText, { color: dec.color }]}>
|
|
70
|
+
{dec.label}
|
|
50
71
|
</Text>
|
|
51
72
|
</View>);
|
|
52
73
|
})}
|
|
@@ -410,9 +431,12 @@ const styles = StyleSheet.create({
|
|
|
410
431
|
fontSize: 9,
|
|
411
432
|
},
|
|
412
433
|
prefixTag: {
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
434
|
+
flexDirection: 'row',
|
|
435
|
+
alignItems: 'center',
|
|
436
|
+
gap: 3.5,
|
|
437
|
+
paddingHorizontal: 6.5,
|
|
438
|
+
paddingVertical: 2,
|
|
439
|
+
borderRadius: 5,
|
|
416
440
|
borderWidth: 1,
|
|
417
441
|
},
|
|
418
442
|
prefixTagText: {
|
|
@@ -6,6 +6,6 @@ export declare class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBo
|
|
|
6
6
|
componentDidCatch(error: Error, errorInfo: ErrorInfo): void;
|
|
7
7
|
private handleReset;
|
|
8
8
|
private handleCopyTrace;
|
|
9
|
-
render():
|
|
9
|
+
render(): React.ReactNode;
|
|
10
10
|
}
|
|
11
11
|
export default ErrorBoundary;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { StyleSheet
|
|
1
|
+
import { Component } from 'react';
|
|
2
|
+
import { StyleSheet } from 'react-native';
|
|
3
3
|
import { AppColors } from '../styles/AppColors';
|
|
4
4
|
import { AppFonts } from '../styles/AppFonts';
|
|
5
5
|
import { copyToClipboard } from '../helpers';
|
|
6
|
-
import {
|
|
6
|
+
import { handleInterceptedCrash } from '../customHooks/crashHandler';
|
|
7
|
+
import { CrashType } from '../types/enums';
|
|
7
8
|
function parseStackTrace(stack) {
|
|
8
9
|
if (!stack)
|
|
9
10
|
return null;
|
|
@@ -68,119 +69,15 @@ ${error.stack}`;
|
|
|
68
69
|
return { hasError: true, error };
|
|
69
70
|
}
|
|
70
71
|
componentDidCatch(error, errorInfo) {
|
|
71
|
-
|
|
72
|
+
try {
|
|
73
|
+
const stack = error?.stack || errorInfo?.componentStack;
|
|
74
|
+
handleInterceptedCrash(error, stack, false, CrashType.Render, errorInfo?.componentStack);
|
|
75
|
+
}
|
|
76
|
+
catch { }
|
|
72
77
|
}
|
|
73
78
|
render() {
|
|
74
79
|
if (this.state.hasError) {
|
|
75
|
-
|
|
76
|
-
if (isInline) {
|
|
77
|
-
return (<View style={styles.inlineContainer}>
|
|
78
|
-
<View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
|
|
79
|
-
<WarningTriangleIcon color={AppColors.redErrorText} size={14}/>
|
|
80
|
-
<Text style={styles.inlineTitle}>Inspector Crash</Text>
|
|
81
|
-
</View>
|
|
82
|
-
<TouchableOpacity style={styles.inlineResetBtn} onPress={this.handleReset}>
|
|
83
|
-
<Text style={styles.inlineResetText}>Reload</Text>
|
|
84
|
-
</TouchableOpacity>
|
|
85
|
-
</View>);
|
|
86
|
-
}
|
|
87
|
-
const error = this.state.error;
|
|
88
|
-
const isNativeCrash = error ? (error.message.includes('Native') || error.message.includes('native') || error.message.includes('Swift') || error.message.includes('Java')) : false;
|
|
89
|
-
const parsed = error && error.stack ? parseStackTrace(error.stack) : null;
|
|
90
|
-
return (<View style={styles.container}>
|
|
91
|
-
<View style={styles.card}>
|
|
92
|
-
<View style={{ marginBottom: 12, alignItems: 'center' }}>
|
|
93
|
-
<WarningTriangleIcon color={AppColors.amber500} size={44}/>
|
|
94
|
-
</View>
|
|
95
|
-
<Text style={styles.title}>Something went wrong</Text>
|
|
96
|
-
|
|
97
|
-
<View style={{
|
|
98
|
-
flexDirection: 'row',
|
|
99
|
-
alignItems: 'center',
|
|
100
|
-
backgroundColor: isNativeCrash ? `${AppColors.errorColor}1A` : `${AppColors.amber500}1A`,
|
|
101
|
-
paddingHorizontal: 10,
|
|
102
|
-
paddingVertical: 4,
|
|
103
|
-
borderRadius: 20,
|
|
104
|
-
marginBottom: 12,
|
|
105
|
-
gap: 4
|
|
106
|
-
}}>
|
|
107
|
-
<View style={{
|
|
108
|
-
width: 8,
|
|
109
|
-
height: 8,
|
|
110
|
-
borderRadius: 4,
|
|
111
|
-
backgroundColor: isNativeCrash ? AppColors.errorColor : AppColors.amber500,
|
|
112
|
-
}}/>
|
|
113
|
-
<Text style={{
|
|
114
|
-
fontSize: 10,
|
|
115
|
-
fontWeight: 'bold',
|
|
116
|
-
color: isNativeCrash ? AppColors.errorColor : AppColors.amber500,
|
|
117
|
-
fontFamily: AppFonts.interBold || 'System'
|
|
118
|
-
}}>
|
|
119
|
-
{isNativeCrash ? 'NATIVE CRASH' : 'JAVASCRIPT CRASH'}
|
|
120
|
-
</Text>
|
|
121
|
-
</View>
|
|
122
|
-
|
|
123
|
-
<Text style={styles.subtitle}>
|
|
124
|
-
The In-App Inspector or active view encountered an error. Traceback details are parsed below:
|
|
125
|
-
</Text>
|
|
126
|
-
|
|
127
|
-
{parsed && (<View style={{
|
|
128
|
-
backgroundColor: AppColors.slate100,
|
|
129
|
-
borderRadius: 8,
|
|
130
|
-
padding: 10,
|
|
131
|
-
width: '100%',
|
|
132
|
-
marginBottom: 10,
|
|
133
|
-
borderWidth: 1,
|
|
134
|
-
borderColor: AppColors.slate200,
|
|
135
|
-
gap: 4
|
|
136
|
-
}}>
|
|
137
|
-
<Text style={{ fontSize: 11, color: AppColors.slate600, fontFamily: AppFonts.interMedium }} numberOfLines={1}>
|
|
138
|
-
<Text style={{ fontWeight: 'bold' }}>Method:</Text> {parsed.method}
|
|
139
|
-
</Text>
|
|
140
|
-
<Text style={{ fontSize: 11, color: AppColors.slate600, fontFamily: AppFonts.interMedium }} numberOfLines={1}>
|
|
141
|
-
<Text style={{ fontWeight: 'bold' }}>File:</Text> {parsed.file}
|
|
142
|
-
</Text>
|
|
143
|
-
<Text style={{ fontSize: 11, color: AppColors.slate600, fontFamily: AppFonts.interMedium }}>
|
|
144
|
-
<Text style={{ fontWeight: 'bold' }}>Line:</Text> {parsed.line} <Text style={{ fontWeight: 'bold' }}>Col:</Text> {parsed.column}
|
|
145
|
-
</Text>
|
|
146
|
-
</View>)}
|
|
147
|
-
|
|
148
|
-
{error && (<ScrollView style={styles.scroll} contentContainerStyle={styles.scrollContent}>
|
|
149
|
-
<Text style={styles.code}>
|
|
150
|
-
{error.message}
|
|
151
|
-
{'\n\n'}
|
|
152
|
-
{error.stack}
|
|
153
|
-
</Text>
|
|
154
|
-
</ScrollView>)}
|
|
155
|
-
|
|
156
|
-
<View style={{ width: '100%', gap: 8, marginBottom: 12 }}>
|
|
157
|
-
<TouchableOpacity style={{
|
|
158
|
-
backgroundColor: AppColors.slate900,
|
|
159
|
-
height: 38,
|
|
160
|
-
borderRadius: 8,
|
|
161
|
-
justifyContent: 'center',
|
|
162
|
-
alignItems: 'center',
|
|
163
|
-
flexDirection: 'row',
|
|
164
|
-
gap: 6
|
|
165
|
-
}} onPress={this.handleCopyTrace}>
|
|
166
|
-
<CopyIcon color={AppColors.white} size={14}/>
|
|
167
|
-
<Text style={{ color: AppColors.white, fontSize: 12, fontWeight: 'bold', fontFamily: AppFonts.interBold || 'System' }}>
|
|
168
|
-
Copy Crash Traceback
|
|
169
|
-
</Text>
|
|
170
|
-
</TouchableOpacity>
|
|
171
|
-
</View>
|
|
172
|
-
|
|
173
|
-
<View style={styles.btnRow}>
|
|
174
|
-
<TouchableOpacity style={styles.resetBtn} onPress={this.handleReset}>
|
|
175
|
-
<Text style={styles.resetBtnText}>Retry / Reload</Text>
|
|
176
|
-
</TouchableOpacity>
|
|
177
|
-
|
|
178
|
-
{this.props.onClose && (<TouchableOpacity style={styles.closeBtn} onPress={this.props.onClose}>
|
|
179
|
-
<Text style={styles.closeBtnText}>Close Inspector</Text>
|
|
180
|
-
</TouchableOpacity>)}
|
|
181
|
-
</View>
|
|
182
|
-
</View>
|
|
183
|
-
</View>);
|
|
80
|
+
return null;
|
|
184
81
|
}
|
|
185
82
|
return this.props.children;
|
|
186
83
|
}
|