react-native-inapp-inspector 2.2.2 → 2.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/dist/commonjs/constants/version.d.ts +1 -1
  2. package/dist/commonjs/constants/version.js +1 -1
  3. package/dist/esm/constants/version.d.ts +1 -1
  4. package/dist/esm/constants/version.js +1 -1
  5. package/package.json +2 -1
  6. package/src/analytics.ts +35 -0
  7. package/src/bundle.ts +25 -0
  8. package/src/components/AnalyticsDetail.tsx +865 -0
  9. package/src/components/AnalyticsEventCard.tsx +441 -0
  10. package/src/components/AnalyticsGraph.tsx +583 -0
  11. package/src/components/AnimatedEntrance.tsx +64 -0
  12. package/src/components/AppHeaderLogo.tsx +109 -0
  13. package/src/components/BrandCircleIcon.tsx +144 -0
  14. package/src/components/BrandSquareIcon.tsx +144 -0
  15. package/src/components/CodeSnippet.tsx +725 -0
  16. package/src/components/ConsoleLogCard.tsx +628 -0
  17. package/src/components/CopyButton.tsx +87 -0
  18. package/src/components/DiffViewer.tsx +82 -0
  19. package/src/components/DomainHeader.tsx +237 -0
  20. package/src/components/EmptyState.tsx +73 -0
  21. package/src/components/EndOfListFooter.tsx +100 -0
  22. package/src/components/ErrorBoundary.tsx +688 -0
  23. package/src/components/HeadersSection.tsx +192 -0
  24. package/src/components/HighlightText.tsx +100 -0
  25. package/src/components/Inspector/AnalyticsFilterModal.tsx +1250 -0
  26. package/src/components/Inspector/AnalyticsTab.tsx +1336 -0
  27. package/src/components/Inspector/BundleTab.tsx +4731 -0
  28. package/src/components/Inspector/ConsoleTab.tsx +702 -0
  29. package/src/components/Inspector/CrashDetail.tsx +941 -0
  30. package/src/components/Inspector/CrashFilterModal.tsx +721 -0
  31. package/src/components/Inspector/CrashTab.tsx +871 -0
  32. package/src/components/Inspector/FabLauncher.tsx +80 -0
  33. package/src/components/Inspector/InspectorContext.tsx +28 -0
  34. package/src/components/Inspector/InspectorHeader.tsx +973 -0
  35. package/src/components/Inspector/LogDetail.tsx +1427 -0
  36. package/src/components/Inspector/MainScreen.tsx +258 -0
  37. package/src/components/Inspector/NavigationTracker.tsx +13 -0
  38. package/src/components/Inspector/NetworkDetail.tsx +794 -0
  39. package/src/components/Inspector/NetworkTab.tsx +1095 -0
  40. package/src/components/Inspector/NpmUpdateToast.tsx +392 -0
  41. package/src/components/Inspector/PerformanceTab.tsx +1894 -0
  42. package/src/components/Inspector/ReduxDetail.tsx +1651 -0
  43. package/src/components/Inspector/ReduxTab.tsx +954 -0
  44. package/src/components/Inspector/SettingsPanel.tsx +3181 -0
  45. package/src/components/Inspector/TabBar.tsx +187 -0
  46. package/src/components/Inspector/TelemetryConsentModal.tsx +392 -0
  47. package/src/components/Inspector/UpdateAvailableModal.tsx +545 -0
  48. package/src/components/JsonViewer.tsx +486 -0
  49. package/src/components/LogCard.tsx +491 -0
  50. package/src/components/LogSyntaxHighlighter.tsx +178 -0
  51. package/src/components/MetaAccordion.tsx +340 -0
  52. package/src/components/MiniBarChart.tsx +42 -0
  53. package/src/components/MiniLineChart.tsx +33 -0
  54. package/src/components/NetworkIcons.tsx +2118 -0
  55. package/src/components/SectionHeader.tsx +113 -0
  56. package/src/components/SegmentedTabs.tsx +83 -0
  57. package/src/components/Slider.tsx +300 -0
  58. package/src/components/SourcePageCard.tsx +148 -0
  59. package/src/components/Toast.tsx +131 -0
  60. package/src/components/TouchableScale.tsx +91 -0
  61. package/src/components/TreeNode.tsx +186 -0
  62. package/src/console.ts +24 -0
  63. package/src/constants/index.ts +38 -0
  64. package/src/constants/version.ts +3 -0
  65. package/src/crash.ts +32 -0
  66. package/src/customHooks/analyticsLogger.ts +336 -0
  67. package/src/customHooks/bundleAnalyzer.ts +1231 -0
  68. package/src/customHooks/consoleLogger.ts +497 -0
  69. package/src/customHooks/crashHandler.ts +944 -0
  70. package/src/customHooks/logFilters.ts +32 -0
  71. package/src/customHooks/networkLogger.ts +419 -0
  72. package/src/customHooks/performanceTracker.ts +1014 -0
  73. package/src/customHooks/reduxLogger.ts +406 -0
  74. package/src/customHooks/useAccordion.tsx +60 -0
  75. package/src/decorators/index.ts +184 -0
  76. package/src/helpers/gaAnalyticsRegistry.ts +204 -0
  77. package/src/helpers/index.ts +860 -0
  78. package/src/helpers/memoryManager.ts +138 -0
  79. package/src/helpers/searchQueryParser.ts +283 -0
  80. package/src/helpers/settingsStore.ts +171 -0
  81. package/src/helpers/telemetry.ts +505 -0
  82. package/src/helpers/toast.ts +17 -0
  83. package/src/i18n/index.ts +69 -0
  84. package/src/i18n/locales/en.json +1052 -0
  85. package/src/index.tsx +2336 -0
  86. package/src/native/NativeInspector.ts +397 -0
  87. package/src/native/NativeNetworkInspector.ts +24 -0
  88. package/src/network.ts +22 -0
  89. package/src/performance.ts +38 -0
  90. package/src/redux.ts +23 -0
  91. package/src/styles/AppColors.ts +408 -0
  92. package/src/styles/AppFonts.ts +8 -0
  93. package/src/styles/common.ts +209 -0
  94. package/src/styles/index.ts +1570 -0
  95. package/src/types/enums.ts +194 -0
  96. package/src/types/index.ts +34 -0
  97. package/src/types/interfaces.ts +515 -0
@@ -0,0 +1,688 @@
1
+ import React, { Component, ErrorInfo } from 'react';
2
+ import {
3
+ StyleSheet,
4
+ Text,
5
+ View,
6
+ ScrollView,
7
+ TouchableOpacity,
8
+ SafeAreaView,
9
+ } from 'react-native';
10
+ import { AppColors } from '../styles/AppColors';
11
+ import { AppFonts } from '../styles/AppFonts';
12
+ import { copyToClipboard } from '../helpers';
13
+ import { t } from '../i18n';
14
+ import { ErrorBoundaryProps, ErrorBoundaryState } from '../types';
15
+ import {
16
+ WarningTriangleIcon,
17
+ CopyIcon,
18
+ RefreshCcwIcon,
19
+ ClearIcon,
20
+ CircleAlertIcon,
21
+ } from './NetworkIcons';
22
+ import { handleInterceptedCrash } from '../customHooks/crashHandler';
23
+ import { CrashType } from '../types/enums';
24
+ import {
25
+ showNativeFloatingButton,
26
+ setNativeFloatingButtonBadge,
27
+ } from '../native/NativeInspector';
28
+
29
+ interface ParsedFrame {
30
+ method: string;
31
+ file: string;
32
+ fullPath: string;
33
+ line: string;
34
+ column: string;
35
+ isProjectFile: boolean;
36
+ }
37
+
38
+ function parseStackTrace(stack: string): { rootFrame: ParsedFrame | null; frames: ParsedFrame[] } {
39
+ if (!stack) return { rootFrame: null, frames: [] };
40
+ const lines = stack.split('\n');
41
+ const frames: ParsedFrame[] = [];
42
+
43
+ for (const line of lines) {
44
+ if (
45
+ line.includes('ErrorBoundary') ||
46
+ line.includes('getDerivedStateFromError') ||
47
+ line.includes('componentDidCatch') ||
48
+ line.includes('handleInterceptedCrash')
49
+ ) {
50
+ continue;
51
+ }
52
+
53
+ // iOS format: method@url:line:col
54
+ const iosMatch = line.match(/^([^@]*)@(.*):(\d+):(\d+)$/);
55
+ if (iosMatch) {
56
+ const [, method, fullPath, lineNum, colNum] = iosMatch;
57
+ const cleanFile = fullPath.split('?')[0].split('/').pop() || fullPath;
58
+ const isProject = !fullPath.includes('node_modules') && !fullPath.includes('Libraries/Core');
59
+ frames.push({
60
+ method: method.trim() || 'anonymous',
61
+ file: cleanFile,
62
+ fullPath: fullPath.split('?')[0],
63
+ line: lineNum,
64
+ column: colNum,
65
+ isProjectFile: isProject,
66
+ });
67
+ continue;
68
+ }
69
+
70
+ // Android format: at method (url:line:col) or at url:line:col
71
+ const androidMatch = line.match(/^\s*at\s+(.+)\s+\((.+):(\d+):(\d+)\)$/);
72
+ if (androidMatch) {
73
+ const [, method, fullPath, lineNum, colNum] = androidMatch;
74
+ const cleanFile = fullPath.split('?')[0].split('/').pop() || fullPath;
75
+ const isProject = !fullPath.includes('node_modules') && !fullPath.includes('Libraries/Core');
76
+ frames.push({
77
+ method: method.trim(),
78
+ file: cleanFile,
79
+ fullPath: fullPath.split('?')[0],
80
+ line: lineNum,
81
+ column: colNum,
82
+ isProjectFile: isProject,
83
+ });
84
+ continue;
85
+ }
86
+
87
+ const androidMatchSimple = line.match(/^\s*at\s+(.+):(\d+):(\d+)$/);
88
+ if (androidMatchSimple) {
89
+ const [, fullPath, lineNum, colNum] = androidMatchSimple;
90
+ const cleanFile = fullPath.split('?')[0].split('/').pop() || fullPath;
91
+ const isProject = !fullPath.includes('node_modules') && !fullPath.includes('Libraries/Core');
92
+ frames.push({
93
+ method: 'anonymous',
94
+ file: cleanFile,
95
+ fullPath: fullPath.split('?')[0],
96
+ line: lineNum,
97
+ column: colNum,
98
+ isProjectFile: isProject,
99
+ });
100
+ }
101
+ }
102
+
103
+ // Find topmost project frame, or fallback to first frame
104
+ const rootFrame = frames.find(f => f.isProjectFile) || frames[0] || null;
105
+ return { rootFrame, frames };
106
+ }
107
+
108
+ export class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
109
+ public state: ErrorBoundaryState = {
110
+ hasError: false,
111
+ error: null,
112
+ };
113
+
114
+ public static getDerivedStateFromError(error: Error): ErrorBoundaryState {
115
+ return { hasError: true, error };
116
+ }
117
+
118
+ public componentDidCatch(error: Error, errorInfo: ErrorInfo) {
119
+ try {
120
+ const stack = error?.stack || errorInfo?.componentStack || '';
121
+ handleInterceptedCrash(
122
+ error,
123
+ stack,
124
+ false,
125
+ CrashType.Render,
126
+ errorInfo?.componentStack,
127
+ );
128
+ showNativeFloatingButton();
129
+ setNativeFloatingButtonBadge(true);
130
+ } catch {}
131
+ }
132
+
133
+ private handleReset = () => {
134
+ this.setState({ hasError: false, error: null });
135
+ if (this.props.onReset) {
136
+ this.props.onReset();
137
+ }
138
+ };
139
+
140
+ private handleCopyTrace = () => {
141
+ const error = this.state.error;
142
+ if (error) {
143
+ const { rootFrame } = parseStackTrace(error.stack || '');
144
+ const detailStr = `─────────────────────────────────────────────────────────────
145
+ IN-APP INSPECTOR • INTERCEPTED CRASH REPORT
146
+ ─────────────────────────────────────────────────────────────
147
+ Error: ${error.name || 'Error'}
148
+ Message: ${error.message}
149
+ ${rootFrame ? `Location: ${rootFrame.file}:${rootFrame.line}:${rootFrame.column}\nMethod: ${rootFrame.method}\nPath: ${rootFrame.fullPath}` : ''}
150
+ Timestamp: ${new Date().toISOString()}
151
+
152
+ Stack Trace:
153
+ ${error.stack || 'No stack trace available'}
154
+ ─────────────────────────────────────────────────────────────`;
155
+ copyToClipboard(detailStr, t('errors.errorReport'));
156
+ }
157
+ };
158
+
159
+ public render() {
160
+ const { hasError, error } = this.state;
161
+ if (!hasError || !error) {
162
+ return this.props.children;
163
+ }
164
+
165
+ const { rootFrame, frames } = parseStackTrace(error.stack || '');
166
+ const errorType = error.name || t('errors.title');
167
+ const isSyntaxOrType =
168
+ errorType.includes('Syntax') ||
169
+ errorType.includes('Type') ||
170
+ errorType.includes('Reference');
171
+
172
+ // ─── Inline Fallback View ─────────────────────────────────────────────
173
+ if (this.props.fallbackType === 'inline') {
174
+ return (
175
+ <View style={styles.inlineContainer}>
176
+ <View style={styles.inlineHeader}>
177
+ <WarningTriangleIcon color={AppColors.red600} size={18} />
178
+ <View style={{ flex: 1 }}>
179
+ <Text style={styles.inlineTitle} numberOfLines={1}>
180
+ {errorType}: {error.message}
181
+ </Text>
182
+ {rootFrame && (
183
+ <Text style={styles.inlineLoc} numberOfLines={1}>
184
+ {rootFrame.file}:{rootFrame.line} ({rootFrame.method})
185
+ </Text>
186
+ )}
187
+ </View>
188
+ </View>
189
+ <View style={styles.inlineActions}>
190
+ <TouchableOpacity
191
+ onPress={this.handleReset}
192
+ style={styles.inlineBtn}
193
+ activeOpacity={0.7}>
194
+ <RefreshCcwIcon size={12} color={AppColors.white} />
195
+ <Text style={styles.inlineBtnText}>{t('errors.retry')}</Text>
196
+ </TouchableOpacity>
197
+ <TouchableOpacity
198
+ onPress={this.handleCopyTrace}
199
+ style={styles.inlineCopyBtn}
200
+ activeOpacity={0.7}>
201
+ <CopyIcon size={12} color={AppColors.redErrorText} />
202
+ <Text style={styles.inlineCopyBtnText}>{t('errors.copy')}</Text>
203
+ </TouchableOpacity>
204
+ </View>
205
+ </View>
206
+ );
207
+ }
208
+
209
+ // ─── Full-Screen Custom Native Recovery Modal ─────────────────────────
210
+ return (
211
+ <SafeAreaView style={styles.safeArea}>
212
+ <View style={styles.container}>
213
+ {/* Header Banner */}
214
+ <View style={styles.header}>
215
+ <View style={styles.iconGlowWrap}>
216
+ <WarningTriangleIcon color={AppColors.red500} size={28} />
217
+ </View>
218
+ <View style={{ flex: 1 }}>
219
+ <View style={styles.badgeRow}>
220
+ <View style={styles.crashBadge}>
221
+ <Text style={styles.crashBadgeText}>
222
+ {isSyntaxOrType ? `JS ${errorType.toUpperCase()}` : t('errors.crashIntercepted')}
223
+ </Text>
224
+ </View>
225
+ <View style={styles.shieldBadge}>
226
+ <Text style={styles.shieldBadgeText}>{t('errors.protected')}</Text>
227
+ </View>
228
+ </View>
229
+ <Text style={styles.title}>{t('errors.rootCauseTitle')}</Text>
230
+ <Text style={styles.subtitle}>{t('errors.rootCauseSubtitle')}</Text>
231
+ </View>
232
+ {this.props.onClose && (
233
+ <TouchableOpacity
234
+ onPress={this.props.onClose}
235
+ style={styles.closeIconBtn}
236
+ activeOpacity={0.7}>
237
+ <ClearIcon size={16} color={AppColors.slate400} />
238
+ </TouchableOpacity>
239
+ )}
240
+ </View>
241
+
242
+ <ScrollView
243
+ style={styles.scrollArea}
244
+ contentContainerStyle={styles.scrollContent}
245
+ showsVerticalScrollIndicator={false}>
246
+ {/* Error Message Box */}
247
+ <View style={styles.errorBox}>
248
+ <View style={styles.errorBoxHeader}>
249
+ <CircleAlertIcon size={14} color={AppColors.red500} />
250
+ <Text style={styles.errorBoxTitle}>{errorType}</Text>
251
+ </View>
252
+ <Text style={styles.errorMessage}>{error.message}</Text>
253
+ </View>
254
+
255
+ {/* Root Cause Location Card */}
256
+ {rootFrame && (
257
+ <View style={styles.locationCard}>
258
+ <Text style={styles.cardHeaderTitle}>{t('errors.exactLocation')}</Text>
259
+ <View style={styles.locRow}>
260
+ <Text style={styles.locLabel}>{t('errors.file')}</Text>
261
+ <Text style={styles.locValFile} numberOfLines={1}>
262
+ {rootFrame.file}
263
+ </Text>
264
+ </View>
265
+ <View style={styles.locRow}>
266
+ <Text style={styles.locLabel}>{t('errors.lineCol')}</Text>
267
+ <Text style={styles.locValNum}>
268
+ {t('errors.lineColVal', {line: rootFrame.line, col: rootFrame.column})}
269
+ </Text>
270
+ </View>
271
+ <View style={styles.locRow}>
272
+ <Text style={styles.locLabel}>{t('errors.function')}</Text>
273
+ <Text style={styles.locValMethod}>{rootFrame.method}()</Text>
274
+ </View>
275
+ {rootFrame.fullPath ? (
276
+ <Text style={styles.fullPathText} numberOfLines={2}>
277
+ {rootFrame.fullPath}
278
+ </Text>
279
+ ) : null}
280
+ </View>
281
+ )}
282
+
283
+ {/* Formatted Stack Frames */}
284
+ <View style={styles.stackCard}>
285
+ <View style={styles.stackCardHeader}>
286
+ <Text style={styles.cardHeaderTitle}>{t('errors.callStack')}</Text>
287
+ <Text style={styles.frameCountText}>
288
+ {t('errors.framesCount', {count: frames.length})}
289
+ </Text>
290
+ </View>
291
+
292
+ {frames.slice(0, 8).map((frame, idx) => (
293
+ <View
294
+ key={idx}
295
+ style={[
296
+ styles.frameItem,
297
+ frame.isProjectFile && styles.frameItemProject,
298
+ ]}>
299
+ <View style={styles.frameNumBadge}>
300
+ <Text
301
+ style={[
302
+ styles.frameNumText,
303
+ frame.isProjectFile && { color: AppColors.sky400 },
304
+ ]}>
305
+ #{idx + 1}
306
+ </Text>
307
+ </View>
308
+ <View style={{ flex: 1 }}>
309
+ <Text
310
+ style={[
311
+ styles.frameMethod,
312
+ frame.isProjectFile && styles.frameMethodProject,
313
+ ]}
314
+ numberOfLines={1}>
315
+ {frame.method}
316
+ </Text>
317
+ <Text style={styles.frameLoc} numberOfLines={1}>
318
+ {frame.file}:{frame.line}:{frame.column}
319
+ </Text>
320
+ </View>
321
+ {frame.isProjectFile && (
322
+ <View style={styles.appTag}>
323
+ <Text style={styles.appTagText}>{t('errors.appTag')}</Text>
324
+ </View>
325
+ )}
326
+ </View>
327
+ ))}
328
+ </View>
329
+ </ScrollView>
330
+
331
+ {/* Action Buttons Footer */}
332
+ <View style={styles.footer}>
333
+ <TouchableOpacity
334
+ onPress={this.handleReset}
335
+ style={styles.retryBtn}
336
+ activeOpacity={0.8}>
337
+ <RefreshCcwIcon size={16} color={AppColors.white} />
338
+ <Text style={styles.retryBtnText}>{t('errors.tryAgainRecover')}</Text>
339
+ </TouchableOpacity>
340
+
341
+ <TouchableOpacity
342
+ onPress={this.handleCopyTrace}
343
+ style={styles.copyBtn}
344
+ activeOpacity={0.8}>
345
+ <CopyIcon size={16} color={AppColors.slate900} />
346
+ <Text style={styles.copyBtnText}>{t('errors.copyDiagnostics')}</Text>
347
+ </TouchableOpacity>
348
+ </View>
349
+ </View>
350
+ </SafeAreaView>
351
+ );
352
+ }
353
+ }
354
+
355
+ const styles = StyleSheet.create({
356
+ safeArea: {
357
+ flex: 1,
358
+ backgroundColor: AppColors.slate850,
359
+ },
360
+ container: {
361
+ flex: 1,
362
+ backgroundColor: AppColors.slate850,
363
+ },
364
+ header: {
365
+ flexDirection: 'row',
366
+ alignItems: 'flex-start',
367
+ paddingHorizontal: 16,
368
+ paddingTop: 14,
369
+ paddingBottom: 12,
370
+ borderBottomWidth: 1,
371
+ borderBottomColor: AppColors.slate800,
372
+ gap: 12,
373
+ },
374
+ iconGlowWrap: {
375
+ width: 44,
376
+ height: 44,
377
+ borderRadius: 12,
378
+ backgroundColor: `${AppColors.red500}26`,
379
+ borderWidth: 1,
380
+ borderColor: `${AppColors.red500}59`,
381
+ alignItems: 'center',
382
+ justifyContent: 'center',
383
+ marginTop: 2,
384
+ },
385
+ badgeRow: {
386
+ flexDirection: 'row',
387
+ alignItems: 'center',
388
+ gap: 6,
389
+ marginBottom: 4,
390
+ },
391
+ crashBadge: {
392
+ backgroundColor: `${AppColors.red500}33`,
393
+ paddingHorizontal: 7,
394
+ paddingVertical: 2,
395
+ borderRadius: 4,
396
+ borderWidth: 1,
397
+ borderColor: `${AppColors.red500}66`,
398
+ },
399
+ crashBadgeText: {
400
+ fontFamily: AppFonts.interBold,
401
+ fontSize: 9.5,
402
+ color: AppColors.red500,
403
+ letterSpacing: 0.5,
404
+ },
405
+ shieldBadge: {
406
+ backgroundColor: `${AppColors.emerald500}26`,
407
+ paddingHorizontal: 6,
408
+ paddingVertical: 2,
409
+ borderRadius: 4,
410
+ borderWidth: 1,
411
+ borderColor: `${AppColors.emerald500}4D`,
412
+ },
413
+ shieldBadgeText: {
414
+ fontFamily: AppFonts.interBold,
415
+ fontSize: 9,
416
+ color: AppColors.emerald500,
417
+ letterSpacing: 0.5,
418
+ },
419
+ title: {
420
+ fontFamily: AppFonts.interBold,
421
+ fontSize: 16,
422
+ color: AppColors.white,
423
+ letterSpacing: -0.2,
424
+ },
425
+ subtitle: {
426
+ fontFamily: AppFonts.interRegular,
427
+ fontSize: 11,
428
+ color: AppColors.slate400,
429
+ marginTop: 1,
430
+ },
431
+ closeIconBtn: {
432
+ padding: 6,
433
+ borderRadius: 8,
434
+ backgroundColor: AppColors.slate800,
435
+ },
436
+ scrollArea: {
437
+ flex: 1,
438
+ },
439
+ scrollContent: {
440
+ padding: 16,
441
+ gap: 12,
442
+ },
443
+ errorBox: {
444
+ backgroundColor: `${AppColors.red500}1A`,
445
+ borderRadius: 12,
446
+ borderWidth: 1,
447
+ borderColor: `${AppColors.red500}40`,
448
+ padding: 14,
449
+ gap: 6,
450
+ },
451
+ errorBoxHeader: {
452
+ flexDirection: 'row',
453
+ alignItems: 'center',
454
+ gap: 6,
455
+ },
456
+ errorBoxTitle: {
457
+ fontFamily: AppFonts.interBold,
458
+ fontSize: 12,
459
+ color: AppColors.red500,
460
+ letterSpacing: 0.3,
461
+ },
462
+ errorMessage: {
463
+ fontFamily: AppFonts.interBold,
464
+ fontSize: 13.5,
465
+ color: AppColors.red100,
466
+ lineHeight: 19,
467
+ },
468
+ locationCard: {
469
+ backgroundColor: AppColors.slate800,
470
+ borderRadius: 12,
471
+ padding: 14,
472
+ borderWidth: 1,
473
+ borderColor: AppColors.slate700,
474
+ gap: 8,
475
+ },
476
+ cardHeaderTitle: {
477
+ fontFamily: AppFonts.interBold,
478
+ fontSize: 10.5,
479
+ color: AppColors.slate400,
480
+ letterSpacing: 0.8,
481
+ },
482
+ locRow: {
483
+ flexDirection: 'row',
484
+ alignItems: 'center',
485
+ justifyContent: 'space-between',
486
+ gap: 8,
487
+ },
488
+ locLabel: {
489
+ fontFamily: AppFonts.interMedium,
490
+ fontSize: 12,
491
+ color: AppColors.slate400,
492
+ minWidth: 80,
493
+ },
494
+ locValFile: {
495
+ fontFamily: AppFonts.interBold,
496
+ fontSize: 12.5,
497
+ color: AppColors.sky400,
498
+ flex: 1,
499
+ textAlign: 'right',
500
+ },
501
+ locValNum: {
502
+ fontFamily: AppFonts.interBold,
503
+ fontSize: 12,
504
+ color: AppColors.white,
505
+ },
506
+ locValMethod: {
507
+ fontFamily: AppFonts.interMedium,
508
+ fontSize: 12,
509
+ color: AppColors.purple400,
510
+ },
511
+ fullPathText: {
512
+ fontFamily: AppFonts.interRegular,
513
+ fontSize: 10,
514
+ color: AppColors.slate500,
515
+ marginTop: 2,
516
+ paddingTop: 6,
517
+ borderTopWidth: 1,
518
+ borderTopColor: AppColors.slate700,
519
+ },
520
+ stackCard: {
521
+ backgroundColor: AppColors.slate800,
522
+ borderRadius: 12,
523
+ padding: 14,
524
+ borderWidth: 1,
525
+ borderColor: AppColors.slate700,
526
+ gap: 8,
527
+ },
528
+ stackCardHeader: {
529
+ flexDirection: 'row',
530
+ justifyContent: 'space-between',
531
+ alignItems: 'center',
532
+ marginBottom: 4,
533
+ },
534
+ frameCountText: {
535
+ fontFamily: AppFonts.interMedium,
536
+ fontSize: 10.5,
537
+ color: AppColors.slate400,
538
+ },
539
+ frameItem: {
540
+ flexDirection: 'row',
541
+ alignItems: 'center',
542
+ backgroundColor: AppColors.slate850,
543
+ padding: 10,
544
+ borderRadius: 8,
545
+ gap: 10,
546
+ borderWidth: 1,
547
+ borderColor: AppColors.slate800,
548
+ },
549
+ frameItemProject: {
550
+ borderColor: `${AppColors.sky400}4D`,
551
+ backgroundColor: `${AppColors.sky400}0D`,
552
+ },
553
+ frameNumBadge: {
554
+ width: 24,
555
+ alignItems: 'center',
556
+ },
557
+ frameNumText: {
558
+ fontFamily: AppFonts.interBold,
559
+ fontSize: 10.5,
560
+ color: AppColors.slate500,
561
+ },
562
+ frameMethod: {
563
+ fontFamily: AppFonts.interBold,
564
+ fontSize: 11.5,
565
+ color: AppColors.slate200,
566
+ },
567
+ frameMethodProject: {
568
+ color: AppColors.white,
569
+ },
570
+ frameLoc: {
571
+ fontFamily: AppFonts.interRegular,
572
+ fontSize: 10,
573
+ color: AppColors.slate400,
574
+ marginTop: 1,
575
+ },
576
+ appTag: {
577
+ backgroundColor: `${AppColors.sky400}33`,
578
+ paddingHorizontal: 5,
579
+ paddingVertical: 2,
580
+ borderRadius: 4,
581
+ },
582
+ appTagText: {
583
+ fontFamily: AppFonts.interBold,
584
+ fontSize: 8.5,
585
+ color: AppColors.sky400,
586
+ },
587
+ footer: {
588
+ flexDirection: 'row',
589
+ padding: 14,
590
+ backgroundColor: AppColors.slate800,
591
+ borderTopWidth: 1,
592
+ borderTopColor: AppColors.slate700,
593
+ gap: 10,
594
+ },
595
+ retryBtn: {
596
+ flex: 1.2,
597
+ flexDirection: 'row',
598
+ alignItems: 'center',
599
+ justifyContent: 'center',
600
+ gap: 8,
601
+ backgroundColor: AppColors.purple,
602
+ height: 44,
603
+ borderRadius: 10,
604
+ },
605
+ retryBtnText: {
606
+ fontFamily: AppFonts.interBold,
607
+ fontSize: 13,
608
+ color: AppColors.white,
609
+ },
610
+ copyBtn: {
611
+ flex: 1,
612
+ flexDirection: 'row',
613
+ alignItems: 'center',
614
+ justifyContent: 'center',
615
+ gap: 8,
616
+ backgroundColor: AppColors.slate100,
617
+ height: 44,
618
+ borderRadius: 10,
619
+ },
620
+ copyBtnText: {
621
+ fontFamily: AppFonts.interBold,
622
+ fontSize: 13,
623
+ color: AppColors.slate900,
624
+ },
625
+ inlineContainer: {
626
+ padding: 12,
627
+ backgroundColor: AppColors.red50,
628
+ borderWidth: 1,
629
+ borderColor: AppColors.errorBorder,
630
+ borderRadius: 10,
631
+ margin: 8,
632
+ gap: 10,
633
+ },
634
+ inlineHeader: {
635
+ flexDirection: 'row',
636
+ alignItems: 'flex-start',
637
+ gap: 10,
638
+ },
639
+ inlineTitle: {
640
+ fontFamily: AppFonts.interBold,
641
+ fontSize: 12,
642
+ color: AppColors.red600,
643
+ },
644
+ inlineLoc: {
645
+ fontFamily: AppFonts.interMedium,
646
+ fontSize: 10.5,
647
+ color: AppColors.redErrorText,
648
+ marginTop: 2,
649
+ },
650
+ inlineActions: {
651
+ flexDirection: 'row',
652
+ gap: 8,
653
+ justifyContent: 'flex-end',
654
+ },
655
+ inlineBtn: {
656
+ flexDirection: 'row',
657
+ alignItems: 'center',
658
+ gap: 4,
659
+ backgroundColor: AppColors.red600,
660
+ paddingHorizontal: 10,
661
+ paddingVertical: 5,
662
+ borderRadius: 6,
663
+ },
664
+ inlineBtnText: {
665
+ fontFamily: AppFonts.interBold,
666
+ fontSize: 11,
667
+ color: AppColors.white,
668
+ },
669
+ inlineCopyBtn: {
670
+ flexDirection: 'row',
671
+ alignItems: 'center',
672
+ gap: 4,
673
+ backgroundColor: AppColors.red100,
674
+ borderWidth: 1,
675
+ borderColor: AppColors.errorBorder,
676
+ paddingHorizontal: 10,
677
+ paddingVertical: 5,
678
+ borderRadius: 6,
679
+ },
680
+ inlineCopyBtnText: {
681
+ fontFamily: AppFonts.interMedium,
682
+ fontSize: 11,
683
+ color: AppColors.redErrorText,
684
+ },
685
+ });
686
+
687
+ export default ErrorBoundary;
688
+