react-native-inapp-inspector 1.0.8 → 1.0.10
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/README.md +5 -6
- package/assets/social_preview.png +0 -0
- package/dist/commonjs/components/AnalyticsDetail.js +28 -23
- package/dist/commonjs/components/AnalyticsEventCard.js +9 -9
- package/dist/commonjs/components/BrandCircleIcon.d.ts +5 -0
- package/dist/commonjs/components/BrandCircleIcon.js +180 -0
- package/dist/commonjs/components/BrandSquareIcon.d.ts +5 -0
- package/dist/commonjs/components/BrandSquareIcon.js +180 -0
- package/dist/commonjs/components/CodeSnippet.js +32 -24
- package/dist/commonjs/components/ConsoleLogCard.js +127 -70
- package/dist/commonjs/components/JsonViewer.d.ts +2 -1
- package/dist/commonjs/components/JsonViewer.js +2 -2
- package/dist/commonjs/components/MetaAccordion.d.ts +1 -1
- package/dist/commonjs/components/MetaAccordion.js +45 -2
- package/dist/commonjs/components/NetworkIcons.d.ts +8 -0
- package/dist/commonjs/components/NetworkIcons.js +44 -1
- package/dist/commonjs/components/ReduxTreeView.d.ts +6 -0
- package/dist/commonjs/components/ReduxTreeView.js +403 -0
- package/dist/commonjs/components/TouchableScale.js +15 -1
- package/dist/commonjs/components/TreeNode.js +3 -3
- package/dist/commonjs/customHooks/reduxLogger.d.ts +4 -0
- package/dist/commonjs/customHooks/reduxLogger.js +48 -2
- package/dist/commonjs/index.js +1520 -506
- package/dist/commonjs/styles/index.d.ts +11 -1
- package/dist/commonjs/styles/index.js +19 -9
- package/dist/commonjs/types/index.d.ts +4 -0
- package/dist/esm/components/AnalyticsDetail.js +28 -23
- package/dist/esm/components/AnalyticsEventCard.js +9 -9
- package/dist/esm/components/BrandCircleIcon.d.ts +5 -0
- package/dist/esm/components/BrandCircleIcon.js +140 -0
- package/dist/esm/components/BrandSquareIcon.d.ts +5 -0
- package/dist/esm/components/BrandSquareIcon.js +140 -0
- package/dist/esm/components/CodeSnippet.js +32 -24
- package/dist/esm/components/ConsoleLogCard.js +127 -70
- package/dist/esm/components/JsonViewer.d.ts +2 -1
- package/dist/esm/components/JsonViewer.js +2 -2
- package/dist/esm/components/MetaAccordion.d.ts +1 -1
- package/dist/esm/components/MetaAccordion.js +46 -3
- package/dist/esm/components/NetworkIcons.d.ts +8 -0
- package/dist/esm/components/NetworkIcons.js +35 -0
- package/dist/esm/components/ReduxTreeView.d.ts +6 -0
- package/dist/esm/components/ReduxTreeView.js +366 -0
- package/dist/esm/components/TouchableScale.js +16 -2
- package/dist/esm/components/TreeNode.js +3 -3
- package/dist/esm/customHooks/reduxLogger.d.ts +4 -0
- package/dist/esm/customHooks/reduxLogger.js +43 -1
- package/dist/esm/index.js +1523 -509
- package/dist/esm/styles/index.d.ts +11 -1
- package/dist/esm/styles/index.js +19 -9
- package/dist/esm/types/index.d.ts +4 -0
- package/example/App.tsx +46 -0
- package/package.json +7 -5
|
@@ -224,7 +224,7 @@ const getStyleForType = (type) => {
|
|
|
224
224
|
case 'value':
|
|
225
225
|
return styles.value;
|
|
226
226
|
default:
|
|
227
|
-
return styles.plain;
|
|
227
|
+
return [styles.plain, { color: AppColors.primaryBlack }];
|
|
228
228
|
}
|
|
229
229
|
};
|
|
230
230
|
const ArrowUpIcon = ({ color = '#64748B', size = 16 }) => (<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
@@ -258,26 +258,32 @@ const CodeSnippetLine = React.memo(({ line, lineIndex, language, search, isActiv
|
|
|
258
258
|
};
|
|
259
259
|
return (<View style={[styles.lineRow, isActiveMatch && styles.activeMatchRow]}>
|
|
260
260
|
{/* Gutter Line Number */}
|
|
261
|
-
<View style={[styles.gutter, isActiveMatch && styles.activeMatchGutter]}>
|
|
262
|
-
<Text style={[styles.lineNumber, isActiveMatch && styles.activeMatchLineNumber]}>{lineIndex + 1}</Text>
|
|
261
|
+
<View style={[styles.gutter, { backgroundColor: AppColors.grayBackground, borderRightColor: AppColors.grayBorderSecondary }, isActiveMatch && styles.activeMatchGutter]}>
|
|
262
|
+
<Text style={[styles.lineNumber, { color: AppColors.grayTextWeak }, isActiveMatch && styles.activeMatchLineNumber]}>{lineIndex + 1}</Text>
|
|
263
263
|
</View>
|
|
264
264
|
|
|
265
265
|
{/* Highlighted Code Line */}
|
|
266
266
|
<View style={styles.codeLine}>
|
|
267
|
-
<Text style={styles.codeLineText}>
|
|
268
|
-
{tokens.length === 0 ? (<Text style={styles.plain}> </Text>) : (tokens.map((token, tokenIdx) => (<React.Fragment key={tokenIdx}>
|
|
267
|
+
<Text style={[styles.codeLineText, { color: AppColors.primaryBlack }]}>
|
|
268
|
+
{tokens.length === 0 ? (<Text style={[styles.plain, { color: AppColors.primaryBlack }]}> </Text>) : (tokens.map((token, tokenIdx) => (<React.Fragment key={tokenIdx}>
|
|
269
269
|
{renderTokenText(token.text, token.type)}
|
|
270
270
|
</React.Fragment>)))}
|
|
271
271
|
</Text>
|
|
272
272
|
</View>
|
|
273
273
|
</View>);
|
|
274
274
|
});
|
|
275
|
-
const CodeSnippet = ({ code, language, }) => {
|
|
275
|
+
const CodeSnippet = ({ code, language, search, }) => {
|
|
276
276
|
const [searchQuery, setSearchQuery] = useState('');
|
|
277
277
|
const [debouncedQuery, setDebouncedQuery] = useState('');
|
|
278
278
|
const [currentMatchIdx, setCurrentMatchIdx] = useState(-1);
|
|
279
279
|
const [visibleLinesCount, setVisibleLinesCount] = useState(200);
|
|
280
280
|
const flatListRef = useRef(null);
|
|
281
|
+
// Sync prop search to searchQuery
|
|
282
|
+
useEffect(() => {
|
|
283
|
+
if (search !== undefined) {
|
|
284
|
+
setSearchQuery(search);
|
|
285
|
+
}
|
|
286
|
+
}, [search]);
|
|
281
287
|
// Debounce search query updates
|
|
282
288
|
useEffect(() => {
|
|
283
289
|
const timer = setTimeout(() => {
|
|
@@ -322,7 +328,7 @@ const CodeSnippet = ({ code, language, }) => {
|
|
|
322
328
|
// Reset scroll and states on code/language changes
|
|
323
329
|
useEffect(() => {
|
|
324
330
|
setVisibleLinesCount(200);
|
|
325
|
-
setSearchQuery('');
|
|
331
|
+
setSearchQuery(search || '');
|
|
326
332
|
setCurrentMatchIdx(-1);
|
|
327
333
|
}, [code, language]);
|
|
328
334
|
// Auto-scroll to the first match when search query returns matches
|
|
@@ -348,32 +354,32 @@ const CodeSnippet = ({ code, language, }) => {
|
|
|
348
354
|
try {
|
|
349
355
|
flatListRef.current?.scrollToIndex({
|
|
350
356
|
index: lineIdx,
|
|
351
|
-
animated:
|
|
352
|
-
viewPosition: 0.
|
|
357
|
+
animated: false,
|
|
358
|
+
viewPosition: 0.3,
|
|
353
359
|
});
|
|
354
360
|
}
|
|
355
361
|
catch (e) {
|
|
356
362
|
// Fallback recovery is handled by onScrollToIndexFailed
|
|
357
363
|
}
|
|
358
|
-
},
|
|
364
|
+
}, 50);
|
|
359
365
|
};
|
|
360
366
|
const onScrollToIndexFailed = (error) => {
|
|
361
367
|
flatListRef.current?.scrollToOffset({
|
|
362
368
|
offset: error.averageItemLength * error.index,
|
|
363
|
-
animated:
|
|
369
|
+
animated: false,
|
|
364
370
|
});
|
|
365
371
|
setTimeout(() => {
|
|
366
372
|
try {
|
|
367
373
|
flatListRef.current?.scrollToIndex({
|
|
368
374
|
index: error.index,
|
|
369
|
-
animated:
|
|
370
|
-
viewPosition: 0.
|
|
375
|
+
animated: false,
|
|
376
|
+
viewPosition: 0.3,
|
|
371
377
|
});
|
|
372
378
|
}
|
|
373
379
|
catch (err) {
|
|
374
380
|
console.warn('Scroll to line index failed after fallback retry:', err);
|
|
375
381
|
}
|
|
376
|
-
},
|
|
382
|
+
}, 60);
|
|
377
383
|
};
|
|
378
384
|
const handleNextMatch = () => {
|
|
379
385
|
if (matches.length === 0)
|
|
@@ -404,12 +410,12 @@ const CodeSnippet = ({ code, language, }) => {
|
|
|
404
410
|
return (<View style={{ flex: 1 }}>
|
|
405
411
|
{/* Search Header Row */}
|
|
406
412
|
<View style={styles.searchRow}>
|
|
407
|
-
<View style={styles.searchBar}>
|
|
413
|
+
<View style={[styles.searchBar, { backgroundColor: AppColors.primaryLight, borderColor: AppColors.grayBorderSecondary }]}>
|
|
408
414
|
<SearchIcon color={AppColors.grayTextWeak} size={15}/>
|
|
409
|
-
<TextInput placeholder={`Search ${language.toUpperCase()}...`} placeholderTextColor={AppColors.grayTextWeak} value={searchQuery} onChangeText={setSearchQuery} style={styles.searchInput} autoCorrect={false} autoCapitalize="none"/>
|
|
415
|
+
<TextInput placeholder={`Search ${language.toUpperCase()}...`} placeholderTextColor={AppColors.grayTextWeak} value={searchQuery} onChangeText={setSearchQuery} style={[styles.searchInput, { color: AppColors.primaryBlack }]} autoCorrect={false} autoCapitalize="none"/>
|
|
410
416
|
|
|
411
417
|
{/* Matches Info */}
|
|
412
|
-
{debouncedQuery.length >= 2 && (<Text style={styles.matchCountText}>
|
|
418
|
+
{debouncedQuery.length >= 2 && (<Text style={[styles.matchCountText, { backgroundColor: AppColors.grayBackground, color: AppColors.grayTextWeak }]}>
|
|
413
419
|
{matches.length > 0 ? `${currentMatchIdx + 1}/${matches.length}` : '0/0'}
|
|
414
420
|
</Text>)}
|
|
415
421
|
|
|
@@ -419,12 +425,12 @@ const CodeSnippet = ({ code, language, }) => {
|
|
|
419
425
|
</View>
|
|
420
426
|
|
|
421
427
|
{/* Up / Down Arrow Navigation Buttons */}
|
|
422
|
-
{matches.length > 0 && (<View style={styles.navArrowsGroup}>
|
|
428
|
+
{matches.length > 0 && (<View style={[styles.navArrowsGroup, { backgroundColor: AppColors.primaryLight, borderColor: AppColors.grayBorderSecondary }]}>
|
|
423
429
|
<TouchableScale onPress={handlePrevMatch} hitSlop={8} style={styles.navArrowBtn}>
|
|
424
|
-
<ArrowUpIcon color=
|
|
430
|
+
<ArrowUpIcon color={AppColors.grayTextStrong} size={14}/>
|
|
425
431
|
</TouchableScale>
|
|
426
432
|
<TouchableScale onPress={handleNextMatch} hitSlop={8} style={styles.navArrowBtn}>
|
|
427
|
-
<ArrowDownIcon color=
|
|
433
|
+
<ArrowDownIcon color={AppColors.grayTextStrong} size={14}/>
|
|
428
434
|
</TouchableScale>
|
|
429
435
|
</View>)}
|
|
430
436
|
|
|
@@ -432,7 +438,7 @@ const CodeSnippet = ({ code, language, }) => {
|
|
|
432
438
|
</View>
|
|
433
439
|
|
|
434
440
|
{/* Code Snippet list container */}
|
|
435
|
-
<View style={styles.container}>
|
|
441
|
+
<View style={[styles.container, { backgroundColor: AppColors.grayBackground, borderColor: AppColors.grayBorderSecondary }]}>
|
|
436
442
|
<FlatList ref={flatListRef} data={visibleLines} renderItem={renderLine} keyExtractor={(_, index) => String(index)} maxToRenderPerBatch={30} windowSize={5} initialNumToRender={50} removeClippedSubviews={Platform.OS === 'android'} onEndReached={handleEndReached} onEndReachedThreshold={0.5} onScrollToIndexFailed={onScrollToIndexFailed}/>
|
|
437
443
|
</View>
|
|
438
444
|
</View>);
|
|
@@ -508,7 +514,9 @@ const styles = StyleSheet.create({
|
|
|
508
514
|
paddingVertical: 1,
|
|
509
515
|
},
|
|
510
516
|
activeMatchRow: {
|
|
511
|
-
backgroundColor: 'rgba(234, 179, 8, 0.
|
|
517
|
+
backgroundColor: 'rgba(234, 179, 8, 0.22)',
|
|
518
|
+
borderLeftWidth: 4,
|
|
519
|
+
borderLeftColor: '#EAB308',
|
|
512
520
|
},
|
|
513
521
|
gutter: {
|
|
514
522
|
width: 40,
|
|
@@ -521,8 +529,8 @@ const styles = StyleSheet.create({
|
|
|
521
529
|
paddingTop: 1,
|
|
522
530
|
},
|
|
523
531
|
activeMatchGutter: {
|
|
524
|
-
backgroundColor: 'rgba(234, 179, 8, 0.
|
|
525
|
-
borderRightColor: 'rgba(234, 179, 8, 0.
|
|
532
|
+
backgroundColor: 'rgba(234, 179, 8, 0.35)',
|
|
533
|
+
borderRightColor: 'rgba(234, 179, 8, 0.5)',
|
|
526
534
|
},
|
|
527
535
|
lineNumber: {
|
|
528
536
|
fontFamily: monoFont,
|
|
@@ -115,6 +115,7 @@ export const ConsoleLogCard = React.memo(function ConsoleLogCard({ item, searchS
|
|
|
115
115
|
const isUserLog = !isWebView && item.sourceMethod === 'log';
|
|
116
116
|
const caller = 'caller' in item ? item.caller : undefined;
|
|
117
117
|
const getLogColors = () => {
|
|
118
|
+
const isDark = AppColors.primaryLight !== '#FFFFFF';
|
|
118
119
|
if (isWebView) {
|
|
119
120
|
const label = item.type.toUpperCase();
|
|
120
121
|
switch (item.type) {
|
|
@@ -124,7 +125,7 @@ export const ConsoleLogCard = React.memo(function ConsoleLogCard({ item, searchS
|
|
|
124
125
|
badgeBg: `${AppColors.errorColor}15`,
|
|
125
126
|
badgeText: AppColors.errorColor,
|
|
126
127
|
label,
|
|
127
|
-
cardBg: '#FFF5F6',
|
|
128
|
+
cardBg: isDark ? 'rgba(239, 68, 68, 0.15)' : '#FFF5F6',
|
|
128
129
|
};
|
|
129
130
|
case 'warn':
|
|
130
131
|
return {
|
|
@@ -132,15 +133,15 @@ export const ConsoleLogCard = React.memo(function ConsoleLogCard({ item, searchS
|
|
|
132
133
|
badgeBg: `${AppColors.lightOrange}15`,
|
|
133
134
|
badgeText: AppColors.darkOrange || AppColors.lightOrange,
|
|
134
135
|
label,
|
|
135
|
-
cardBg: '#FFFDF6',
|
|
136
|
+
cardBg: isDark ? 'rgba(245, 158, 11, 0.15)' : '#FFFDF6',
|
|
136
137
|
};
|
|
137
138
|
default:
|
|
138
139
|
return {
|
|
139
140
|
border: '#475569',
|
|
140
|
-
badgeBg: '#F1F5F9',
|
|
141
|
-
badgeText: '#475569',
|
|
141
|
+
badgeBg: isDark ? '#374151' : '#F1F5F9',
|
|
142
|
+
badgeText: isDark ? '#9CA3AF' : '#475569',
|
|
142
143
|
label,
|
|
143
|
-
cardBg: '#F8FAFC',
|
|
144
|
+
cardBg: isDark ? '#1E1E24' : '#F8FAFC',
|
|
144
145
|
};
|
|
145
146
|
}
|
|
146
147
|
}
|
|
@@ -150,7 +151,7 @@ export const ConsoleLogCard = React.memo(function ConsoleLogCard({ item, searchS
|
|
|
150
151
|
badgeBg: `${AppColors.skyBlue}15`,
|
|
151
152
|
badgeText: AppColors.skyBlue,
|
|
152
153
|
label: 'ERROR',
|
|
153
|
-
cardBg: '
|
|
154
|
+
cardBg: isDark ? 'rgba(96, 165, 250, 0.15)' : '#E6F2FF',
|
|
154
155
|
};
|
|
155
156
|
}
|
|
156
157
|
switch (item.type) {
|
|
@@ -160,7 +161,7 @@ export const ConsoleLogCard = React.memo(function ConsoleLogCard({ item, searchS
|
|
|
160
161
|
badgeBg: `${AppColors.errorColor}15`,
|
|
161
162
|
badgeText: AppColors.errorColor,
|
|
162
163
|
label: 'ERROR',
|
|
163
|
-
cardBg: '
|
|
164
|
+
cardBg: isDark ? 'rgba(239, 68, 68, 0.15)' : '#FFF5F6',
|
|
164
165
|
};
|
|
165
166
|
case 'warn':
|
|
166
167
|
return {
|
|
@@ -168,16 +169,16 @@ export const ConsoleLogCard = React.memo(function ConsoleLogCard({ item, searchS
|
|
|
168
169
|
badgeBg: `${AppColors.lightOrange}15`,
|
|
169
170
|
badgeText: AppColors.darkOrange || AppColors.lightOrange,
|
|
170
171
|
label: 'WARN',
|
|
171
|
-
cardBg: '
|
|
172
|
+
cardBg: isDark ? 'rgba(245, 158, 11, 0.15)' : '#FFFDF6',
|
|
172
173
|
};
|
|
173
174
|
default:
|
|
174
175
|
if (isUserLog) {
|
|
175
176
|
return {
|
|
176
177
|
border: '#475569',
|
|
177
|
-
badgeBg: '#E2E8F0',
|
|
178
|
-
badgeText: '#334155',
|
|
178
|
+
badgeBg: isDark ? '#374151' : '#E2E8F0',
|
|
179
|
+
badgeText: isDark ? '#D1D5DB' : '#334155',
|
|
179
180
|
label: 'INFO',
|
|
180
|
-
cardBg: '#F1F5F9',
|
|
181
|
+
cardBg: isDark ? '#1E1E24' : '#F1F5F9',
|
|
181
182
|
};
|
|
182
183
|
}
|
|
183
184
|
return {
|
|
@@ -185,7 +186,7 @@ export const ConsoleLogCard = React.memo(function ConsoleLogCard({ item, searchS
|
|
|
185
186
|
badgeBg: `${AppColors.purple}15`,
|
|
186
187
|
badgeText: AppColors.purple,
|
|
187
188
|
label: 'INFO',
|
|
188
|
-
cardBg: '
|
|
189
|
+
cardBg: isDark ? 'rgba(167, 139, 250, 0.12)' : '#F9F5FF',
|
|
189
190
|
};
|
|
190
191
|
}
|
|
191
192
|
};
|
|
@@ -204,84 +205,138 @@ export const ConsoleLogCard = React.memo(function ConsoleLogCard({ item, searchS
|
|
|
204
205
|
borderLeftWidth: 4,
|
|
205
206
|
borderLeftColor: colors.border,
|
|
206
207
|
backgroundColor: colors.cardBg,
|
|
208
|
+
borderColor: AppColors.grayBorderSecondary,
|
|
209
|
+
flexDirection: 'row',
|
|
210
|
+
alignItems: 'center',
|
|
211
|
+
paddingRight: 4,
|
|
207
212
|
},
|
|
208
213
|
]}>
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
214
|
+
|
|
215
|
+
{/* Left Content Area */}
|
|
216
|
+
<Pressable onPress={() => setExpanded(prev => !prev)} style={{ flex: 1, paddingRight: 6 }}>
|
|
217
|
+
|
|
218
|
+
<View style={styles.cardHeader}>
|
|
219
|
+
<View style={styles.headerLeft}>
|
|
220
|
+
<CopyButton value={item.message} label="Log message"/>
|
|
221
|
+
<View style={[styles.badge, { backgroundColor: colors.badgeBg }]}>
|
|
222
|
+
<Text style={[styles.badgeText, { color: colors.badgeText }]}>
|
|
223
|
+
{colors.label}
|
|
224
|
+
</Text>
|
|
225
|
+
</View>
|
|
226
|
+
<View style={[
|
|
227
|
+
styles.badge,
|
|
228
|
+
{
|
|
229
|
+
backgroundColor: 'rgba(107, 78, 255, 0.08)',
|
|
230
|
+
borderColor: 'rgba(107, 78, 255, 0.2)',
|
|
231
|
+
borderWidth: 1,
|
|
232
|
+
},
|
|
233
|
+
]}>
|
|
234
|
+
<Text style={[styles.badgeText, { color: '#6B4EFF' }]}>
|
|
235
|
+
console.{('sourceMethod' in item ? item.sourceMethod : undefined) || item.type || 'log'}
|
|
236
|
+
</Text>
|
|
237
|
+
</View>
|
|
238
|
+
{jsonContent && (<View style={[
|
|
239
|
+
styles.badge,
|
|
240
|
+
{
|
|
241
|
+
backgroundColor: 'rgba(13, 148, 136, 0.08)',
|
|
242
|
+
borderColor: 'rgba(13, 148, 136, 0.18)',
|
|
243
|
+
borderWidth: 1,
|
|
244
|
+
},
|
|
245
|
+
]}>
|
|
246
|
+
<Text style={[styles.badgeText, { color: '#0D9488' }]}>
|
|
247
|
+
{Array.isArray(jsonContent.data) ? `Array[${jsonContent.data.length}]` : `Object{${Object.keys(jsonContent.data).length}}`}
|
|
248
|
+
</Text>
|
|
249
|
+
</View>)}
|
|
250
|
+
{isAnalyticsError && (<View style={[
|
|
218
251
|
styles.badge,
|
|
219
252
|
{ backgroundColor: `${AppColors.skyBlue}15` },
|
|
220
253
|
]}>
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
254
|
+
<Text style={[styles.badgeText, { color: AppColors.skyBlue }]}>
|
|
255
|
+
Analytics
|
|
256
|
+
</Text>
|
|
257
|
+
</View>)}
|
|
258
|
+
{isUserLog && (<View style={[
|
|
226
259
|
styles.badge,
|
|
227
260
|
{
|
|
228
|
-
backgroundColor:
|
|
229
|
-
borderColor:
|
|
261
|
+
backgroundColor: AppColors.grayBackground,
|
|
262
|
+
borderColor: AppColors.grayBorderSecondary,
|
|
230
263
|
borderWidth: 1,
|
|
231
264
|
},
|
|
232
265
|
]}>
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
266
|
+
<Text style={[styles.badgeText, { color: AppColors.grayTextStrong }]}>
|
|
267
|
+
user-log
|
|
268
|
+
</Text>
|
|
269
|
+
</View>)}
|
|
270
|
+
{isWebView && (<View style={[
|
|
238
271
|
styles.badge,
|
|
239
272
|
{
|
|
240
|
-
backgroundColor:
|
|
241
|
-
borderColor:
|
|
273
|
+
backgroundColor: AppColors.grayBackground,
|
|
274
|
+
borderColor: AppColors.grayBorderSecondary,
|
|
242
275
|
borderWidth: 1,
|
|
243
276
|
},
|
|
244
277
|
]}>
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
{caller && caller !== 'Unknown' && (<Text style={styles.callerText} numberOfLines={1} ellipsizeMode="middle">
|
|
278
|
+
<Text style={[styles.badgeText, { color: AppColors.grayText }]}>
|
|
279
|
+
webview
|
|
280
|
+
</Text>
|
|
281
|
+
</View>)}
|
|
282
|
+
<Text style={[styles.serialNumber, { color: AppColors.grayTextWeak }]}>#{item.id + 1}</Text>
|
|
283
|
+
<Text style={[styles.timestamp, { color: AppColors.grayTextWeak }]}>{formatTime(item.timestamp)}</Text>
|
|
284
|
+
</View>
|
|
285
|
+
|
|
286
|
+
{caller && caller !== 'Unknown' && (<Text style={[styles.callerText, { color: AppColors.grayTextWeak, marginRight: 4 }]} numberOfLines={1} ellipsizeMode="middle">
|
|
254
287
|
{caller.split('/').pop() || caller}
|
|
255
288
|
</Text>)}
|
|
256
|
-
<View style={{ transform: [{ rotate: expanded ? '180deg' : '0deg' }] }}>
|
|
257
|
-
<ChevronIcon size={14} color={AppColors.grayTextWeak}/>
|
|
258
|
-
</View>
|
|
259
289
|
</View>
|
|
290
|
+
|
|
291
|
+
<View style={[styles.cardBody, { backgroundColor: AppColors.primaryLight, borderColor: AppColors.dividerColor }]}>
|
|
292
|
+
{jsonContent ? (<>
|
|
293
|
+
{jsonContent.header ? (<Pressable onPress={() => setExpanded(prev => !prev)}>
|
|
294
|
+
{getLogMessageWithBadges(jsonContent.header, searchStr, [styles.messageText, { color: AppColors.primaryBlack }], styles.highlight, numLines)}
|
|
295
|
+
</Pressable>) : null}
|
|
296
|
+
{expanded ? (<View style={[styles.jsonContainer, { backgroundColor: AppColors.grayBackground, borderColor: AppColors.dividerColor }]}>
|
|
297
|
+
<JsonViewer data={jsonContent.data} search={searchStr} forceOpen={expanded}/>
|
|
298
|
+
</View>) : (<Pressable onPress={() => setExpanded(prev => !prev)} style={[styles.jsonPreviewContainer, { backgroundColor: AppColors.grayBackground, borderColor: AppColors.dividerColor }]}>
|
|
299
|
+
<HighlightText text={getJsonPreviewText(jsonContent.data).text} search={searchStr} style={[styles.jsonPreviewText, { color: AppColors.primaryBlack }]} highlightStyle={styles.highlight} detectLinks={true}/>
|
|
300
|
+
</Pressable>)}
|
|
301
|
+
</>) : (<Pressable onPress={() => setExpanded(prev => !prev)}>
|
|
302
|
+
{getLogMessageWithBadges(item.message, searchStr, [styles.messageText, { color: AppColors.primaryBlack }], styles.highlight, numLines)}
|
|
303
|
+
</Pressable>)}
|
|
304
|
+
{hasLongMessage && (<Pressable onPress={() => setExpanded(prev => !prev)} style={styles.seeMoreBtn} hitSlop={8}>
|
|
305
|
+
<Text style={styles.seeMoreText}>
|
|
306
|
+
{expanded ? 'See Less' : 'See More'}
|
|
307
|
+
</Text>
|
|
308
|
+
</Pressable>)}
|
|
309
|
+
</View>
|
|
310
|
+
|
|
311
|
+
{expanded && (<View style={[styles.cardFooter, { borderTopColor: AppColors.dividerColor, gap: 6 }]}>
|
|
312
|
+
<View style={{ flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' }}>
|
|
313
|
+
<Text style={{ fontFamily: AppFonts.interRegular, fontSize: 10.5, color: AppColors.grayTextWeak }}>
|
|
314
|
+
Length: {item.message.length} chars • Size: {encodeURIComponent(item.message).replace(/%[0-9A-F]{2}/g, 'a').length} bytes
|
|
315
|
+
</Text>
|
|
316
|
+
</View>
|
|
317
|
+
{caller && caller !== 'Unknown' && (<View style={{ flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', marginTop: 4 }}>
|
|
318
|
+
<Text style={[styles.fullCallerText, { color: AppColors.grayText, flex: 1, marginRight: 8 }]} numberOfLines={2}>
|
|
319
|
+
Caller: {caller}
|
|
320
|
+
</Text>
|
|
321
|
+
<CopyButton value={caller} label="Caller stack frame"/>
|
|
322
|
+
</View>)}
|
|
323
|
+
</View>)}
|
|
260
324
|
</Pressable>
|
|
261
325
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
{hasLongMessage && (<Pressable onPress={() => setExpanded(prev => !prev)} style={styles.seeMoreBtn} hitSlop={8}>
|
|
276
|
-
<Text style={styles.seeMoreText}>
|
|
277
|
-
{expanded ? 'See Less' : 'See More'}
|
|
278
|
-
</Text>
|
|
279
|
-
</Pressable>)}
|
|
280
|
-
</View>
|
|
326
|
+
{/* Right Isolated Chevron Area */}
|
|
327
|
+
<Pressable onPress={() => setExpanded(prev => !prev)} style={{
|
|
328
|
+
width: 28,
|
|
329
|
+
alignItems: 'center',
|
|
330
|
+
justifyContent: 'center',
|
|
331
|
+
alignSelf: expanded ? 'flex-start' : 'center',
|
|
332
|
+
marginTop: expanded ? 8 : 0,
|
|
333
|
+
height: expanded ? 32 : undefined,
|
|
334
|
+
}} hitSlop={12}>
|
|
335
|
+
<View style={{ transform: [{ rotate: expanded ? '180deg' : '0deg' }] }}>
|
|
336
|
+
<ChevronIcon size={16} color={AppColors.grayTextWeak}/>
|
|
337
|
+
</View>
|
|
338
|
+
</Pressable>
|
|
281
339
|
|
|
282
|
-
{caller && caller !== 'Unknown' && expanded && (<View style={styles.cardFooter}>
|
|
283
|
-
<Text style={styles.fullCallerText}>Caller: {caller}</Text>
|
|
284
|
-
</View>)}
|
|
285
340
|
</View>
|
|
286
341
|
</View>);
|
|
287
342
|
});
|
|
@@ -314,7 +369,9 @@ const styles = StyleSheet.create({
|
|
|
314
369
|
headerLeft: {
|
|
315
370
|
flexDirection: 'row',
|
|
316
371
|
alignItems: 'center',
|
|
317
|
-
|
|
372
|
+
flexWrap: 'wrap',
|
|
373
|
+
gap: 6,
|
|
374
|
+
flex: 1,
|
|
318
375
|
},
|
|
319
376
|
badge: {
|
|
320
377
|
paddingHorizontal: 6,
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
declare const JsonViewer: ({ data, search, forceOpen, }: {
|
|
2
|
+
declare const JsonViewer: ({ data, search, forceOpen, defaultExpandDepth, }: {
|
|
3
3
|
data: unknown;
|
|
4
4
|
search?: string;
|
|
5
5
|
forceOpen?: boolean;
|
|
6
|
+
defaultExpandDepth?: number;
|
|
6
7
|
}) => React.JSX.Element;
|
|
7
8
|
export default JsonViewer;
|
|
@@ -4,10 +4,10 @@ import { ScrollView, View } from 'react-native';
|
|
|
4
4
|
import TreeNode from './TreeNode';
|
|
5
5
|
// Stylesheet
|
|
6
6
|
import styles from '../styles';
|
|
7
|
-
const JsonViewer = ({ data, search, forceOpen, }) => {
|
|
7
|
+
const JsonViewer = ({ data, search, forceOpen, defaultExpandDepth, }) => {
|
|
8
8
|
return (<ScrollView horizontal showsHorizontalScrollIndicator={true} style={styles.codeBlockScroll}>
|
|
9
9
|
<View style={styles.codeBlock}>
|
|
10
|
-
<TreeNode data={data} search={search} forceOpen={forceOpen}/>
|
|
10
|
+
<TreeNode data={data} search={search} forceOpen={forceOpen} defaultExpandDepth={defaultExpandDepth}/>
|
|
11
11
|
</View>
|
|
12
12
|
</ScrollView>);
|
|
13
13
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { MetaAccordionProps } from '../types';
|
|
3
|
-
declare const MetaAccordion: ({ status, statusColor, duration, size, triggeredAt, }: MetaAccordionProps) => React.JSX.Element;
|
|
3
|
+
declare const MetaAccordion: ({ status, statusColor, duration, size, triggeredAt, method, contentType, url, }: MetaAccordionProps) => React.JSX.Element;
|
|
4
4
|
export default MetaAccordion;
|
|
@@ -7,12 +7,13 @@ import useAccordion from '../customHooks/useAccordion';
|
|
|
7
7
|
// Helpers
|
|
8
8
|
import { getDurationColor } from '../helpers';
|
|
9
9
|
// Assets
|
|
10
|
-
import { ChevronIcon, CalendarIcon, StatusIcon, ClockIcon, SizeIcon, } from './NetworkIcons';
|
|
10
|
+
import { ChevronIcon, CalendarIcon, StatusIcon, ClockIcon, SizeIcon, TerminalIcon, GlobeIcon, } from './NetworkIcons';
|
|
11
11
|
// Stylesheet
|
|
12
12
|
import { AppColors } from '../styles/AppColors';
|
|
13
13
|
import styles from '../styles';
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
import { AppFonts } from '../styles/AppFonts';
|
|
15
|
+
const MetaAccordion = ({ status, statusColor, duration, size, triggeredAt, method, contentType, url, }) => {
|
|
16
|
+
const { toggleOpen, chevronStyle, bodyStyle } = useAccordion(true, 400, 390);
|
|
16
17
|
const isFailed = status === 0 || status == null;
|
|
17
18
|
return (<View style={styles.metaContainer}>
|
|
18
19
|
<Pressable onPress={toggleOpen} hitSlop={12}>
|
|
@@ -39,6 +40,26 @@ const MetaAccordion = ({ status, statusColor, duration, size, triggeredAt, }) =>
|
|
|
39
40
|
</Text>
|
|
40
41
|
</View>
|
|
41
42
|
<View style={styles.metaDivider}/>
|
|
43
|
+
|
|
44
|
+
<View style={styles.metaRow}>
|
|
45
|
+
<View style={styles.metaLabelRow}>
|
|
46
|
+
<TerminalIcon color={AppColors.grayTextWeak} size={14}/>
|
|
47
|
+
<Text style={styles.metaLabel}>Method</Text>
|
|
48
|
+
</View>
|
|
49
|
+
<View style={[
|
|
50
|
+
styles.statusChip,
|
|
51
|
+
{
|
|
52
|
+
borderColor: 'rgba(107, 78, 255, 0.25)',
|
|
53
|
+
backgroundColor: 'rgba(107, 78, 255, 0.08)',
|
|
54
|
+
}
|
|
55
|
+
]}>
|
|
56
|
+
<Text style={[styles.statusText, { color: AppColors.purple, fontFamily: AppFonts.interBold }]}>
|
|
57
|
+
{method || 'GET'}
|
|
58
|
+
</Text>
|
|
59
|
+
</View>
|
|
60
|
+
</View>
|
|
61
|
+
<View style={styles.metaDivider}/>
|
|
62
|
+
|
|
42
63
|
<View style={styles.metaRow}>
|
|
43
64
|
<View style={styles.metaLabelRow}>
|
|
44
65
|
<StatusIcon color={AppColors.grayTextWeak}/>
|
|
@@ -64,6 +85,16 @@ const MetaAccordion = ({ status, statusColor, duration, size, triggeredAt, }) =>
|
|
|
64
85
|
</View>
|
|
65
86
|
</View>
|
|
66
87
|
<View style={styles.metaDivider}/>
|
|
88
|
+
|
|
89
|
+
<View style={styles.metaRow}>
|
|
90
|
+
<View style={styles.metaLabelRow}>
|
|
91
|
+
<GlobeIcon color={AppColors.grayTextWeak} size={14}/>
|
|
92
|
+
<Text style={styles.metaLabel}>Content Type</Text>
|
|
93
|
+
</View>
|
|
94
|
+
<Text style={styles.metaValue}>{contentType || 'application/json'}</Text>
|
|
95
|
+
</View>
|
|
96
|
+
<View style={styles.metaDivider}/>
|
|
97
|
+
|
|
67
98
|
<View style={styles.metaRow}>
|
|
68
99
|
<View style={styles.metaLabelRow}>
|
|
69
100
|
<ClockIcon color={AppColors.grayTextWeak} size={14}/>
|
|
@@ -94,6 +125,7 @@ const MetaAccordion = ({ status, statusColor, duration, size, triggeredAt, }) =>
|
|
|
94
125
|
</View>
|
|
95
126
|
</View>
|
|
96
127
|
<View style={styles.metaDivider}/>
|
|
128
|
+
|
|
97
129
|
<View style={styles.metaRow}>
|
|
98
130
|
<View style={styles.metaLabelRow}>
|
|
99
131
|
<SizeIcon color={AppColors.grayTextWeak}/>
|
|
@@ -101,6 +133,17 @@ const MetaAccordion = ({ status, statusColor, duration, size, triggeredAt, }) =>
|
|
|
101
133
|
</View>
|
|
102
134
|
<Text style={styles.metaValue}>{size}</Text>
|
|
103
135
|
</View>
|
|
136
|
+
<View style={styles.metaDivider}/>
|
|
137
|
+
|
|
138
|
+
<View style={[styles.metaRow, { alignItems: 'flex-start' }]}>
|
|
139
|
+
<View style={styles.metaLabelRow}>
|
|
140
|
+
<GlobeIcon color={AppColors.grayTextWeak} size={14}/>
|
|
141
|
+
<Text style={styles.metaLabel}>Full URL</Text>
|
|
142
|
+
</View>
|
|
143
|
+
<Text selectable={true} numberOfLines={3} ellipsizeMode="tail" style={[styles.metaValue, { fontSize: 11.5, color: AppColors.grayTextWeak, flex: 1, textAlign: 'right', lineHeight: 16 }]}>
|
|
144
|
+
{url || '—'}
|
|
145
|
+
</Text>
|
|
146
|
+
</View>
|
|
104
147
|
</View>
|
|
105
148
|
</Animated.View>
|
|
106
149
|
</View>);
|
|
@@ -34,3 +34,11 @@ export declare const InsightsIcon: ({ color, size, }: any) => React.JSX.Element;
|
|
|
34
34
|
export declare const DebugIcon: ({ color, size }: any) => React.JSX.Element;
|
|
35
35
|
export declare const SunIcon: ({ color, size }: any) => React.JSX.Element;
|
|
36
36
|
export declare const MoonIcon: ({ color, size }: any) => React.JSX.Element;
|
|
37
|
+
export { BrandCircleIcon } from './BrandCircleIcon';
|
|
38
|
+
export { BrandSquareIcon } from './BrandSquareIcon';
|
|
39
|
+
export declare const HtmlIcon: ({ color, size }: any) => React.JSX.Element;
|
|
40
|
+
export declare const CssIcon: ({ color, size }: any) => React.JSX.Element;
|
|
41
|
+
export declare const JsIcon: ({ color, size }: any) => React.JSX.Element;
|
|
42
|
+
export declare const EyeIcon: ({ color, size }: any) => React.JSX.Element;
|
|
43
|
+
export declare const SettingsIcon: ({ color, size }: any) => React.JSX.Element;
|
|
44
|
+
export declare const FolderIcon: ({ color, size }: any) => React.JSX.Element;
|
|
@@ -213,3 +213,38 @@ export const MoonIcon = ({ color = '#FFFFFF', size = 16 }) => {
|
|
|
213
213
|
<Path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" fill={color} stroke={color} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
|
|
214
214
|
</Svg>);
|
|
215
215
|
};
|
|
216
|
+
export { BrandCircleIcon } from './BrandCircleIcon';
|
|
217
|
+
export { BrandSquareIcon } from './BrandSquareIcon';
|
|
218
|
+
export const HtmlIcon = ({ color = AppColors.grayTextWeak, size = 14 }) => {
|
|
219
|
+
return (<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
220
|
+
<Path d="M17.5 8.5L21 12l-3.5 3.5M6.5 8.5L3 12l3.5 3.5M14 4.5l-4 15" stroke={color} strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"/>
|
|
221
|
+
</Svg>);
|
|
222
|
+
};
|
|
223
|
+
export const CssIcon = ({ color = AppColors.grayTextWeak, size = 14 }) => {
|
|
224
|
+
return (<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
225
|
+
<Path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
|
|
226
|
+
</Svg>);
|
|
227
|
+
};
|
|
228
|
+
export const JsIcon = ({ color = AppColors.grayTextWeak, size = 14 }) => {
|
|
229
|
+
return (<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
230
|
+
<Rect x="3" y="3" width="18" height="18" rx="4" stroke={color} strokeWidth="2"/>
|
|
231
|
+
<Path d="M8 12v2.5a1.5 1.5 0 003 0V11M13 15.5a1 1 0 001.5.8h.5a1 1 0 001-1v-.5a1 1 0 00-1-1h-1a1 1 0 01-1-1v-.5a1 1 0 011-1h.5a1 1 0 011.5.8" stroke={color} strokeWidth="2" strokeLinecap="round"/>
|
|
232
|
+
</Svg>);
|
|
233
|
+
};
|
|
234
|
+
export const EyeIcon = ({ color = AppColors.grayTextWeak, size = 14 }) => {
|
|
235
|
+
return (<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
236
|
+
<Path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
|
|
237
|
+
<Circle cx="12" cy="12" r="3" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
|
|
238
|
+
</Svg>);
|
|
239
|
+
};
|
|
240
|
+
export const SettingsIcon = ({ color = AppColors.grayTextWeak, size = 14 }) => {
|
|
241
|
+
return (<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
242
|
+
<Path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
|
|
243
|
+
<Circle cx="12" cy="12" r="3" stroke={color} strokeWidth="2"/>
|
|
244
|
+
</Svg>);
|
|
245
|
+
};
|
|
246
|
+
export const FolderIcon = ({ color = AppColors.grayTextWeak, size = 14 }) => {
|
|
247
|
+
return (<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
248
|
+
<Path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
|
|
249
|
+
</Svg>);
|
|
250
|
+
};
|