react-native-inapp-inspector 2.2.9 → 2.3.1

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 (105) hide show
  1. package/dist/commonjs/components/AppHeaderLogo.js +45 -12
  2. package/dist/commonjs/components/BrandSquareIcon.js +92 -49
  3. package/dist/commonjs/components/EmptyState.d.ts +7 -2
  4. package/dist/commonjs/components/EmptyState.js +11 -5
  5. package/dist/commonjs/components/Inspector/AnalyticsTab.js +29 -18
  6. package/dist/commonjs/components/Inspector/ConsoleTab.js +6 -1
  7. package/dist/commonjs/components/Inspector/CrashDetail.js +43 -9
  8. package/dist/commonjs/components/Inspector/CrashTab.js +34 -3
  9. package/dist/commonjs/components/Inspector/DeviceInfoTab.js +80 -16
  10. package/dist/commonjs/components/Inspector/InspectorHeader.js +16 -3
  11. package/dist/commonjs/components/Inspector/MainScreen.js +7 -11
  12. package/dist/commonjs/components/Inspector/NetworkDetail.js +3 -2
  13. package/dist/commonjs/components/Inspector/NetworkTab.js +103 -4
  14. package/dist/commonjs/components/Inspector/ReduxTab.js +19 -3
  15. package/dist/commonjs/components/Inspector/SettingsPanel.js +4 -4
  16. package/dist/commonjs/components/Inspector/StorageTab.js +123 -92
  17. package/dist/commonjs/components/JsonViewer.js +2 -0
  18. package/dist/commonjs/components/MetaAccordion.js +15 -3
  19. package/dist/commonjs/components/SkeletonPlaceholder.d.ts +6 -0
  20. package/dist/commonjs/components/SkeletonPlaceholder.js +208 -0
  21. package/dist/commonjs/constants/version.d.ts +1 -1
  22. package/dist/commonjs/constants/version.js +1 -1
  23. package/dist/commonjs/customHooks/networkLogger.d.ts +3 -0
  24. package/dist/commonjs/customHooks/networkLogger.js +10 -1
  25. package/dist/commonjs/customHooks/storageInspector.d.ts +2 -2
  26. package/dist/commonjs/customHooks/storageInspector.js +17 -13
  27. package/dist/commonjs/helpers/index.d.ts +6 -0
  28. package/dist/commonjs/helpers/index.js +196 -6
  29. package/dist/commonjs/helpers/searchQueryParser.js +62 -20
  30. package/dist/commonjs/i18n/index.d.ts +13 -0
  31. package/dist/commonjs/i18n/index.js +35 -2
  32. package/dist/commonjs/index.d.ts +3 -0
  33. package/dist/commonjs/index.js +108 -35
  34. package/dist/commonjs/styles/AppColors.d.ts +4 -0
  35. package/dist/commonjs/styles/AppColors.js +11 -1
  36. package/dist/commonjs/styles/AppFonts.d.ts +11 -0
  37. package/dist/commonjs/styles/AppFonts.js +11 -1
  38. package/dist/commonjs/types/interfaces.d.ts +2 -2
  39. package/dist/esm/components/AppHeaderLogo.js +45 -12
  40. package/dist/esm/components/BrandSquareIcon.js +92 -49
  41. package/dist/esm/components/EmptyState.d.ts +7 -2
  42. package/dist/esm/components/EmptyState.js +11 -5
  43. package/dist/esm/components/Inspector/AnalyticsTab.js +30 -19
  44. package/dist/esm/components/Inspector/ConsoleTab.js +6 -1
  45. package/dist/esm/components/Inspector/CrashDetail.js +43 -9
  46. package/dist/esm/components/Inspector/CrashTab.js +34 -3
  47. package/dist/esm/components/Inspector/DeviceInfoTab.js +80 -16
  48. package/dist/esm/components/Inspector/InspectorHeader.js +17 -4
  49. package/dist/esm/components/Inspector/MainScreen.js +8 -12
  50. package/dist/esm/components/Inspector/NetworkDetail.js +3 -2
  51. package/dist/esm/components/Inspector/NetworkTab.js +103 -4
  52. package/dist/esm/components/Inspector/ReduxTab.js +19 -3
  53. package/dist/esm/components/Inspector/SettingsPanel.js +4 -4
  54. package/dist/esm/components/Inspector/StorageTab.js +124 -93
  55. package/dist/esm/components/JsonViewer.js +2 -0
  56. package/dist/esm/components/MetaAccordion.js +15 -3
  57. package/dist/esm/components/SkeletonPlaceholder.d.ts +6 -0
  58. package/dist/esm/components/SkeletonPlaceholder.js +173 -0
  59. package/dist/esm/constants/version.d.ts +1 -1
  60. package/dist/esm/constants/version.js +1 -1
  61. package/dist/esm/customHooks/networkLogger.d.ts +3 -0
  62. package/dist/esm/customHooks/networkLogger.js +8 -0
  63. package/dist/esm/customHooks/storageInspector.d.ts +2 -2
  64. package/dist/esm/customHooks/storageInspector.js +17 -13
  65. package/dist/esm/helpers/index.d.ts +6 -0
  66. package/dist/esm/helpers/index.js +193 -5
  67. package/dist/esm/helpers/searchQueryParser.js +62 -20
  68. package/dist/esm/i18n/index.d.ts +13 -0
  69. package/dist/esm/i18n/index.js +33 -3
  70. package/dist/esm/index.d.ts +3 -0
  71. package/dist/esm/index.js +97 -37
  72. package/dist/esm/styles/AppColors.d.ts +4 -0
  73. package/dist/esm/styles/AppColors.js +9 -0
  74. package/dist/esm/styles/AppFonts.d.ts +11 -0
  75. package/dist/esm/styles/AppFonts.js +9 -0
  76. package/dist/esm/types/interfaces.d.ts +2 -2
  77. package/package.json +1 -1
  78. package/src/components/AppHeaderLogo.tsx +46 -12
  79. package/src/components/BrandSquareIcon.tsx +127 -78
  80. package/src/components/EmptyState.tsx +27 -5
  81. package/src/components/Inspector/AnalyticsTab.tsx +48 -27
  82. package/src/components/Inspector/ConsoleTab.tsx +10 -0
  83. package/src/components/Inspector/CrashDetail.tsx +65 -9
  84. package/src/components/Inspector/CrashTab.tsx +41 -3
  85. package/src/components/Inspector/DeviceInfoTab.tsx +87 -16
  86. package/src/components/Inspector/InspectorHeader.tsx +24 -4
  87. package/src/components/Inspector/MainScreen.tsx +7 -11
  88. package/src/components/Inspector/NetworkDetail.tsx +4 -4
  89. package/src/components/Inspector/NetworkTab.tsx +129 -4
  90. package/src/components/Inspector/ReduxTab.tsx +26 -8
  91. package/src/components/Inspector/SettingsPanel.tsx +4 -4
  92. package/src/components/Inspector/StorageTab.tsx +191 -117
  93. package/src/components/JsonViewer.tsx +2 -0
  94. package/src/components/MetaAccordion.tsx +18 -3
  95. package/src/components/SkeletonPlaceholder.tsx +206 -0
  96. package/src/constants/version.ts +1 -1
  97. package/src/customHooks/networkLogger.ts +15 -0
  98. package/src/customHooks/storageInspector.ts +18 -14
  99. package/src/helpers/index.ts +213 -5
  100. package/src/helpers/searchQueryParser.ts +63 -20
  101. package/src/i18n/index.ts +38 -3
  102. package/src/index.tsx +124 -37
  103. package/src/styles/AppColors.ts +9 -0
  104. package/src/styles/AppFonts.ts +16 -0
  105. package/src/types/interfaces.ts +2 -2
@@ -34,8 +34,12 @@ export const AppHeaderLogo: React.FC<AppHeaderLogoProps> = ({
34
34
  return (
35
35
  <View
36
36
  style={[
37
- logoStyles.container,
38
- {width: size, height: size, padding: 0, borderRadius: Math.round(size * 0.28)},
37
+ logoStyles.svgContainer,
38
+ {
39
+ width: size,
40
+ height: size,
41
+ borderRadius: Math.round(size * 0.23),
42
+ },
39
43
  ]}>
40
44
  {clonedIcon}
41
45
  </View>
@@ -44,8 +48,12 @@ export const AppHeaderLogo: React.FC<AppHeaderLogoProps> = ({
44
48
  return (
45
49
  <View
46
50
  style={[
47
- logoStyles.container,
48
- {width: size, height: size, borderRadius: Math.round(size * 0.28)},
51
+ logoStyles.imageContainer,
52
+ {
53
+ width: size,
54
+ height: size,
55
+ borderRadius: Math.round(size * 0.23),
56
+ },
49
57
  ]}>
50
58
  <Image
51
59
  source={customIcon as ImageSourcePropType}
@@ -65,7 +73,15 @@ export const AppHeaderLogo: React.FC<AppHeaderLogoProps> = ({
65
73
  });
66
74
 
67
75
  return (
68
- <View style={[logoStyles.container, {width: size, height: size}]}>
76
+ <View
77
+ style={[
78
+ logoStyles.imageContainer,
79
+ {
80
+ width: size,
81
+ height: size,
82
+ borderRadius: Math.round(size * 0.23),
83
+ },
84
+ ]}>
69
85
  <Image
70
86
  source={nativeSource}
71
87
  style={logoStyles.image}
@@ -80,8 +96,12 @@ export const AppHeaderLogo: React.FC<AppHeaderLogoProps> = ({
80
96
  return (
81
97
  <View
82
98
  style={[
83
- logoStyles.container,
84
- {width: size, height: size, padding: 0, borderRadius: Math.round(size * 0.28)},
99
+ logoStyles.svgContainer,
100
+ {
101
+ width: size,
102
+ height: size,
103
+ borderRadius: Math.round(size * 0.23),
104
+ },
85
105
  ]}>
86
106
  <BrandSquareIcon size={size} />
87
107
  </View>
@@ -89,20 +109,34 @@ export const AppHeaderLogo: React.FC<AppHeaderLogoProps> = ({
89
109
  };
90
110
 
91
111
  const logoStyles = StyleSheet.create({
92
- container: {
93
- borderRadius: 10,
112
+ svgContainer: {
113
+ overflow: 'hidden',
114
+ alignItems: 'center',
115
+ justifyContent: 'center',
116
+ shadowColor: '#000',
117
+ shadowOffset: {width: 0, height: 2},
118
+ shadowOpacity: 0.25,
119
+ shadowRadius: 3,
120
+ elevation: 3,
121
+ },
122
+ imageContainer: {
94
123
  overflow: 'hidden',
95
124
  backgroundColor: 'rgba(255, 255, 255, 0.15)',
96
125
  borderWidth: 1,
97
- borderColor: 'rgba(255, 255, 255, 0.28)',
98
- padding: 2.5,
126
+ borderColor: 'rgba(255, 255, 255, 0.35)',
127
+ padding: 2,
99
128
  alignItems: 'center',
100
129
  justifyContent: 'center',
130
+ shadowColor: '#000',
131
+ shadowOffset: {width: 0, height: 2},
132
+ shadowOpacity: 0.25,
133
+ shadowRadius: 3,
134
+ elevation: 3,
101
135
  },
102
136
  image: {
103
137
  width: '100%',
104
138
  height: '100%',
105
- borderRadius: 7.5,
139
+ borderRadius: 8,
106
140
  },
107
141
  });
108
142
 
@@ -8,7 +8,6 @@ import Svg, {
8
8
  RadialGradient,
9
9
  Stop,
10
10
  Rect,
11
- Ellipse,
12
11
  Line,
13
12
  } from 'react-native-svg';
14
13
 
@@ -16,117 +15,167 @@ export const BrandSquareIcon = ({size = 56}: {size?: number}) => {
16
15
  return (
17
16
  <Svg width={size} height={size} viewBox="0 0 256 256" fill="none">
18
17
  <Defs>
18
+ {/* App Tile Background - Crisp Royal Deep Violet to Midnight */}
19
19
  <LinearGradient id="bs_tile" x1="0" y1="0" x2="256" y2="256" gradientUnits="userSpaceOnUse">
20
- <Stop offset="0" stopColor="#1E1B4B" />
21
- <Stop offset="1" stopColor="#0F172A" />
20
+ <Stop offset="0%" stopColor="#1E1B4B" />
21
+ <Stop offset="50%" stopColor="#18182F" />
22
+ <Stop offset="100%" stopColor="#0B0F19" />
22
23
  </LinearGradient>
23
- <LinearGradient id="bs_beam" x1="0" y1="0" x2="256" y2="256" gradientUnits="userSpaceOnUse">
24
- <Stop offset="0" stopColor="#818CF8" />
25
- <Stop offset="0.5" stopColor="#A855F7" />
26
- <Stop offset="1" stopColor="#EC4899" />
24
+
25
+ {/* Outer Neon Cyber Border */}
26
+ <LinearGradient id="bs_border" x1="0" y1="0" x2="256" y2="256" gradientUnits="userSpaceOnUse">
27
+ <Stop offset="0%" stopColor="#818CF8" stopOpacity={0.9} />
28
+ <Stop offset="45%" stopColor="#C084FC" stopOpacity={0.8} />
29
+ <Stop offset="80%" stopColor="#F472B6" stopOpacity={0.85} />
30
+ <Stop offset="100%" stopColor="#38BDF8" stopOpacity={0.9} />
27
31
  </LinearGradient>
28
- <LinearGradient id="bs_body" x1="0" y1="0" x2="0" y2="256" gradientUnits="userSpaceOnUse">
29
- <Stop offset="0" stopColor="#312E81" />
30
- <Stop offset="1" stopColor="#1E1B4B" />
32
+
33
+ {/* Ambient Top Glow */}
34
+ <RadialGradient id="bs_top_glow" cx="50%" cy="15%" r="65%">
35
+ <Stop offset="0%" stopColor="#818CF8" stopOpacity={0.35} />
36
+ <Stop offset="60%" stopColor="#A855F7" stopOpacity={0.12} />
37
+ <Stop offset="100%" stopColor="#1E1B4B" stopOpacity={0} />
38
+ </RadialGradient>
39
+
40
+ {/* Owl Outer Body Gradient - High Contrast */}
41
+ <LinearGradient id="bs_body" x1="64" y1="40" x2="192" y2="220" gradientUnits="userSpaceOnUse">
42
+ <Stop offset="0%" stopColor="#3730A3" />
43
+ <Stop offset="50%" stopColor="#2E1065" />
44
+ <Stop offset="100%" stopColor="#17123A" />
31
45
  </LinearGradient>
32
- <RadialGradient id="bs_iris" cx="40%" cy="40%" r="60%">
33
- <Stop offset="0" stopColor="#FDE047" />
34
- <Stop offset="0.7" stopColor="#F59E0B" />
35
- <Stop offset="1" stopColor="#D97706" />
46
+
47
+ {/* Neon Cyber Beam Stroke */}
48
+ <LinearGradient id="bs_beam" x1="40" y1="40" x2="220" y2="220" gradientUnits="userSpaceOnUse">
49
+ <Stop offset="0%" stopColor="#67E8F9" />
50
+ <Stop offset="35%" stopColor="#818CF8" />
51
+ <Stop offset="70%" stopColor="#C084FC" />
52
+ <Stop offset="100%" stopColor="#F472B6" />
53
+ </LinearGradient>
54
+
55
+ {/* Eyes Radiant Iris */}
56
+ <RadialGradient id="bs_iris" cx="38%" cy="36%" r="65%">
57
+ <Stop offset="0%" stopColor="#FEF08A" />
58
+ <Stop offset="40%" stopColor="#FBBF24" />
59
+ <Stop offset="80%" stopColor="#F59E0B" />
60
+ <Stop offset="100%" stopColor="#D97706" />
36
61
  </RadialGradient>
37
- <LinearGradient id="bs_beak" x1="0" y1="0" x2="0" y2="20" gradientUnits="userSpaceOnUse">
38
- <Stop offset="0" stopColor="#FBBF24" />
39
- <Stop offset="1" stopColor="#F97316" />
62
+
63
+ {/* Beak Gradient */}
64
+ <LinearGradient id="bs_beak" x1="124" y1="120" x2="132" y2="136" gradientUnits="userSpaceOnUse">
65
+ <Stop offset="0%" stopColor="#FDE047" />
66
+ <Stop offset="100%" stopColor="#EA580C" />
40
67
  </LinearGradient>
68
+
69
+ {/* Diagnostic Lens Glass Flare */}
70
+ <RadialGradient id="bs_lens" cx="40%" cy="35%" r="65%">
71
+ <Stop offset="0%" stopColor="#A5F3FC" stopOpacity={0.4} />
72
+ <Stop offset="50%" stopColor="#38BDF8" stopOpacity={0.18} />
73
+ <Stop offset="100%" stopColor="#0284C7" stopOpacity={0.05} />
74
+ </RadialGradient>
41
75
  </Defs>
42
76
 
43
- {/* Rounded App Tile Background */}
44
- <Rect x="8" y="8" width="240" height="240" rx="54" fill="url(#bs_tile)" />
77
+ {/* ── 1. Rounded App Tile Base (Full Edge-to-Edge) ── */}
78
+ <Rect x="2" y="2" width="252" height="252" rx="58" fill="url(#bs_tile)" />
79
+ <Rect x="2" y="2" width="252" height="252" rx="58" fill="url(#bs_top_glow)" />
45
80
  <Rect
46
- x="8"
47
- y="8"
48
- width="240"
49
- height="240"
50
- rx="54"
81
+ x="2"
82
+ y="2"
83
+ width="252"
84
+ height="252"
85
+ rx="58"
51
86
  fill="none"
52
- stroke="url(#bs_beam)"
53
- strokeWidth="3"
54
- strokeOpacity={0.4}
87
+ stroke="url(#bs_border)"
88
+ strokeWidth="3.5"
55
89
  />
56
90
 
57
- {/* Owl Outer Body Contour */}
91
+ {/* ── 2. Owl Outer Wings (Layered behind) ── */}
58
92
  <Path
59
- d="M64 148 C60 102 72 68 92 56 L100 40 L118 60 Q128 55 138 60 L156 40 L164 56 C184 68 196 102 192 148 C196 178 182 202 150 210 C138 214 118 214 106 210 C74 202 60 178 64 148 Z"
60
- fill="url(#bs_body)"
93
+ d="M62 120 C42 152 46 194 76 210 C68 178 66 146 80 120 Z"
94
+ fill="#1E1B4B"
61
95
  stroke="url(#bs_beam)"
62
- strokeWidth="4"
63
- strokeLinejoin="round"
96
+ strokeWidth="3"
97
+ strokeOpacity={0.75}
64
98
  />
65
-
66
- {/* Wings */}
67
99
  <Path
68
- d="M74 124 C58 154 60 190 86 204 C79 176 77 148 88 126 Z"
100
+ d="M194 120 C214 152 210 194 180 210 C188 178 190 146 176 120 Z"
69
101
  fill="#1E1B4B"
70
- stroke="#818CF8"
71
- strokeWidth="2.5"
72
- strokeOpacity={0.6}
102
+ stroke="url(#bs_beam)"
103
+ strokeWidth="3"
104
+ strokeOpacity={0.75}
73
105
  />
106
+
107
+ {/* ── 3. Owl Body Contour ── */}
74
108
  <Path
75
- d="M182 124 C198 154 196 190 170 204 C177 176 179 148 168 126 Z"
76
- fill="#1E1B4B"
77
- stroke="#818CF8"
78
- strokeWidth="2.5"
79
- strokeOpacity={0.6}
109
+ d="M58 146 C54 98 68 64 88 52 L98 34 L118 56 Q128 50 138 56 L158 34 L168 52 C188 64 202 98 198 146 C202 180 186 208 152 216 C140 220 116 220 104 216 C70 208 54 180 58 146 Z"
110
+ fill="url(#bs_body)"
111
+ stroke="url(#bs_beam)"
112
+ strokeWidth="4.5"
113
+ strokeLinejoin="round"
80
114
  />
81
115
 
82
- {/* Belly Screen Plate */}
116
+ {/* Inner Ear Highlights */}
117
+ <Path d="M98 42 L112 56 L102 57 Z" fill="#67E8F9" opacity={0.6} />
118
+ <Path d="M158 42 L144 56 L154 57 Z" fill="#F472B6" opacity={0.6} />
119
+
120
+ {/* ── 4. Chest Terminal & Code Braces ── */}
83
121
  <Rect
84
- x="105"
85
- y="160"
86
- width="46"
87
- height="34"
88
- rx="8"
89
- fill="#0B0F19"
122
+ x="98"
123
+ y="162"
124
+ width="60"
125
+ height="38"
126
+ rx="10"
127
+ fill="#050811"
90
128
  stroke="url(#bs_beam)"
91
- strokeWidth="2"
129
+ strokeWidth="2.5"
92
130
  />
93
- {/* Code Emblem on Chest */}
94
- <G stroke="#A5B4FC" strokeWidth="2.8" strokeLinecap="round" strokeLinejoin="round" fill="none">
95
- <Path d="M120 171 L114 177 L120 183" />
96
- <Path d="M136 171 L142 177 L136 183" />
97
- <Path d="M130 169 L126 185" stroke="#EC4899" />
131
+ <G strokeWidth="3" strokeLinecap="round" strokeLinejoin="round" fill="none">
132
+ <Path d="M116 174 L108 181 L116 188" stroke="#38BDF8" />
133
+ <Path d="M140 174 L148 181 L140 188" stroke="#38BDF8" />
134
+ <Path d="M131 171 L125 191" stroke="#F43F5E" />
98
135
  </G>
99
136
 
100
- {/* Facial Disc & Mask */}
137
+ {/* ── 5. Facial Mask Plate ── */}
101
138
  <Path
102
- d="M128 92 C148 70 186 78 186 108 C186 134 160 152 128 152 C96 152 70 134 70 108 C70 78 108 70 128 92 Z"
103
- fill="#2E1065"
104
- stroke="#818CF8"
105
- strokeWidth="2"
106
- strokeOpacity={0.6}
139
+ d="M128 88 C152 64 192 72 192 104 C192 132 162 152 128 152 C94 152 64 132 64 104 C64 72 104 64 128 88 Z"
140
+ fill="#1E1B4B"
141
+ stroke="url(#bs_beam)"
142
+ strokeWidth="2.8"
107
143
  />
108
144
 
109
- {/* Right Eye (Normal Cute Eye) */}
110
- <Circle cx="154" cy="108" r="17" fill="url(#bs_iris)" stroke="#0F172A" strokeWidth="2" />
111
- <Circle cx="154" cy="108" r="8.5" fill="#0F172A" />
112
- <Circle cx="157" cy="105" r="3" fill="#FFFFFF" />
113
- <Circle cx="151" cy="111" r="1.5" fill="#FFFFFF" opacity={0.8} />
145
+ {/* ── 6. Right Eye (Glowing Owl Eye) ── */}
146
+ <Circle cx="156" cy="106" r="19" fill="url(#bs_iris)" stroke="#0F172A" strokeWidth="2.5" />
147
+ <Circle cx="156" cy="106" r="9.5" fill="#0B0F19" />
148
+ <Circle cx="159.5" cy="102.5" r="3.5" fill="#FFFFFF" />
149
+ <Circle cx="153" cy="109.5" r="1.8" fill="#FFFFFF" opacity={0.85} />
150
+
151
+ {/* ── 7. Left Eye (Diagnostic Magnifier Lens) ── */}
152
+ {/* Magnifier Glass Glow */}
153
+ <Circle cx="94" cy="104" r="30" fill="url(#bs_lens)" stroke="url(#bs_beam)" strokeWidth="6" />
154
+ <Line x1="72" y1="126" x2="48" y2="152" stroke="#0B0F19" strokeWidth="13" strokeLinecap="round" />
155
+ <Line x1="72" y1="126" x2="48" y2="152" stroke="url(#bs_beam)" strokeWidth="8" strokeLinecap="round" />
114
156
 
115
- {/* Left Eye (Diagnostic Magnifier Lens) */}
116
- <Circle cx="96" cy="104" r="20" fill="url(#bs_iris)" stroke="#0F172A" strokeWidth="2" />
117
- <Circle cx="96" cy="104" r="10" fill="#0F172A" />
118
- <Circle cx="99.5" cy="100.5" r="3.5" fill="#FFFFFF" />
119
- <Circle cx="92" cy="107" r="1.8" fill="#FFFFFF" opacity={0.8} />
157
+ {/* Eye Inside Magnifier */}
158
+ <Circle cx="94" cy="104" r="21" fill="url(#bs_iris)" stroke="#0F172A" strokeWidth="2.5" />
159
+ <Circle cx="94" cy="104" r="10.5" fill="#0B0F19" />
160
+ <Circle cx="98" cy="100" r="4" fill="#FFFFFF" />
161
+ <Circle cx="90.5" cy="107.5" r="2" fill="#FFFFFF" opacity={0.85} />
120
162
 
121
- {/* Magnifier Glass Ring & Handle */}
122
- <Line x1="76" y1="124" x2="55" y2="148" stroke="#0F172A" strokeWidth="12" strokeLinecap="round" />
123
- <Line x1="76" y1="124" x2="55" y2="148" stroke="url(#bs_beam)" strokeWidth="7" strokeLinecap="round" />
124
- <Circle cx="96" cy="104" r="28" fill="#38BDF8" fillOpacity={0.12} stroke="url(#bs_beam)" strokeWidth="6" />
163
+ {/* Lens Reflection Highlight */}
164
+ <Path
165
+ d="M74 94 A26 26 0 0 1 106 78"
166
+ stroke="#FFFFFF"
167
+ strokeWidth="3"
168
+ strokeLinecap="round"
169
+ opacity={0.65}
170
+ fill="none"
171
+ />
125
172
 
126
- {/* Beak */}
173
+ {/* ── 8. Beak ── */}
127
174
  <Path
128
- d="M123.5 123 Q128 121 132.5 123 Q131 132 128 134.5 Q125 132 123.5 123 Z"
175
+ d="M123 120 Q128 118 133 120 Q131.5 133 128 137 Q124.5 133 123 120 Z"
129
176
  fill="url(#bs_beak)"
177
+ stroke="#78350F"
178
+ strokeWidth="1"
130
179
  />
131
180
  </Svg>
132
181
  );
@@ -12,7 +12,21 @@ import {EmptyRadarIcon} from './NetworkIcons';
12
12
  import {AppColors} from '../styles/AppColors';
13
13
  import styles from '../styles';
14
14
 
15
- const EmptyState = React.memo(function EmptyState({isSearch}: {isSearch?: boolean}) {
15
+ interface EmptyStateProps {
16
+ isSearch?: boolean;
17
+ searchQuery?: string;
18
+ customTitle?: string;
19
+ customSub?: string;
20
+ onClearSearch?: () => void;
21
+ }
22
+
23
+ const EmptyState = React.memo(function EmptyState({
24
+ isSearch,
25
+ searchQuery,
26
+ customTitle,
27
+ customSub,
28
+ onClearSearch,
29
+ }: EmptyStateProps) {
16
30
  const iconPulse = useRef(new Animated.Value(1)).current;
17
31
 
18
32
  useEffect(() => {
@@ -54,13 +68,21 @@ const EmptyState = React.memo(function EmptyState({isSearch}: {isSearch?: boolea
54
68
  <EmptyRadarIcon color={AppColors.purple} size={32} />
55
69
  </Animated.View>
56
70
  <Text style={styles.emptyTitle}>
57
- {isSearch ? 'No matching APIs' : 'No network activity'}
71
+ {customTitle || (isSearch ? 'No matching results' : 'No network activity')}
58
72
  </Text>
59
73
  <Text style={styles.emptySub}>
60
- {isSearch
61
- ? 'Try adjusting your filters or search.'
62
- : 'Listening for incoming API calls...'}
74
+ {customSub ||
75
+ (isSearch
76
+ ? searchQuery
77
+ ? `No items matched "${searchQuery}"`
78
+ : 'Try adjusting your filters or search keywords.'
79
+ : 'Listening for incoming API calls...')}
63
80
  </Text>
81
+ {isSearch && onClearSearch && (
82
+ <TouchableScale style={styles.reloadBtn} onPress={onClearSearch}>
83
+ <Text style={styles.reloadBtnText}>Clear Search & Filters</Text>
84
+ </TouchableScale>
85
+ )}
64
86
  {!isSearch && (
65
87
  <TouchableScale style={styles.reloadBtn} onPress={handleReload}>
66
88
  <Text style={styles.reloadBtnText}>Reload App</Text>
@@ -11,6 +11,7 @@ import {animateNextLayout, useInspector} from './InspectorContext';
11
11
  import AnalyticsEventCard from '../AnalyticsEventCard';
12
12
  import AnalyticsFilterModal from './AnalyticsFilterModal';
13
13
  import EndOfListFooter from '../EndOfListFooter';
14
+ import EmptyState from '../EmptyState';
14
15
  import styles from '../../styles';
15
16
  import {AppColors} from '../../styles/AppColors';
16
17
  import {AppFonts} from '../../styles/AppFonts';
@@ -1183,15 +1184,38 @@ const AnalyticsTab = React.memo(() => {
1183
1184
  autoCapitalize="none"
1184
1185
  />
1185
1186
  {analyticsSearch.length > 0 && (
1186
- <Pressable
1187
- onPress={() => setAnalyticsSearch('')}
1188
- hitSlop={10}
1189
- style={styles.clearBtn}>
1190
- <ClearIcon
1191
- color={AppColors.grayTextWeak}
1192
- size={14}
1193
- />
1194
- </Pressable>
1187
+ <View
1188
+ style={{
1189
+ flexDirection: 'row',
1190
+ alignItems: 'center',
1191
+ gap: 4,
1192
+ }}>
1193
+ <View
1194
+ style={{
1195
+ backgroundColor: `${AppColors.purple}20`,
1196
+ borderRadius: 10,
1197
+ paddingHorizontal: 6,
1198
+ paddingVertical: 1.5,
1199
+ }}>
1200
+ <Text
1201
+ style={{
1202
+ color: AppColors.purple,
1203
+ fontSize: 9.5,
1204
+ fontFamily: AppFonts.interBold,
1205
+ }}>
1206
+ {filteredAnalyticsEvents.length}
1207
+ </Text>
1208
+ </View>
1209
+ <Pressable
1210
+ onPress={() => setAnalyticsSearch('')}
1211
+ hitSlop={10}
1212
+ style={styles.clearBtn}>
1213
+ <ClearIcon
1214
+ color={AppColors.grayTextWeak}
1215
+ size={13}
1216
+ />
1217
+ </Pressable>
1218
+ </View>
1195
1219
  )}
1196
1220
  </View>
1197
1221
  <View style={styles.toolbarRight}>
@@ -1292,24 +1316,21 @@ const AnalyticsTab = React.memo(() => {
1292
1316
  removeClippedSubviews={true}
1293
1317
  renderToHardwareTextureAndroid={true}
1294
1318
  ListEmptyComponent={
1295
- <View style={styles.emptyContainer}>
1296
- <View style={styles.emptyIconWrap}>
1297
- <EmptyRadarIcon
1298
- color={AppColors.purple}
1299
- size={32}
1300
- />
1301
- </View>
1302
- <Text style={styles.emptyTitle}>
1303
- {analyticsSearch.length > 0
1304
- ? 'No matching events'
1305
- : 'No analytics events yet'}
1306
- </Text>
1307
- <Text style={styles.emptySub}>
1308
- {analyticsSearch.length > 0
1309
- ? 'Try adjusting your search.'
1310
- : 'Call setupAnalyticsLogger(analytics()) at app start.'}
1311
- </Text>
1312
- </View>
1319
+ <EmptyState
1320
+ isSearch={analyticsSearch.length > 0}
1321
+ searchQuery={analyticsSearch}
1322
+ customTitle={
1323
+ analyticsSearch.length > 0
1324
+ ? 'No matching analytics events'
1325
+ : 'No analytics events yet'
1326
+ }
1327
+ customSub={
1328
+ analyticsSearch.length > 0
1329
+ ? `No events matched "${analyticsSearch}"`
1330
+ : 'Call setupAnalyticsLogger(analytics()) at app start.'
1331
+ }
1332
+ onClearSearch={() => setAnalyticsSearch('')}
1333
+ />
1313
1334
  }
1314
1335
  ListFooterComponent={
1315
1336
  filteredAnalyticsEvents.length > 0 ? (
@@ -682,6 +682,16 @@ const ConsoleTab = React.memo(() => {
682
682
  isSearch={
683
683
  logSearch.length > 0 || logFilters.size > 0
684
684
  }
685
+ searchQuery={logSearch}
686
+ customTitle={
687
+ logSearch.length > 0
688
+ ? 'No matching console logs'
689
+ : 'No console logs'
690
+ }
691
+ onClearSearch={() => {
692
+ setLogSearch('');
693
+ setLogFilters(new Set());
694
+ }}
685
695
  />
686
696
  }
687
697
  ListFooterComponent={
@@ -13,6 +13,7 @@ import TouchableScale from '../TouchableScale';
13
13
  import SegmentedTabs from '../SegmentedTabs';
14
14
  import HighlightText from '../HighlightText';
15
15
  import JsonViewer from '../JsonViewer';
16
+ import CopyButton from '../CopyButton';
16
17
  import {AppColors} from '../../styles/AppColors';
17
18
  import {AppFonts} from '../../styles/AppFonts';
18
19
  import {
@@ -485,9 +486,27 @@ const CrashDetail: React.FC = React.memo(() => {
485
486
  <View style={{gap: 12}}>
486
487
  {/* Device & OS Diagnostics Card */}
487
488
  <View style={localStyles.sectionCard}>
488
- <View style={localStyles.sectionCardHeader}>
489
- <GlobeIcon color={AppColors.purple} size={14} />
490
- <Text style={localStyles.sectionCardTitle}>{t('crash.deviceEnvironment')}</Text>
489
+ <View
490
+ style={[
491
+ localStyles.sectionCardHeader,
492
+ {justifyContent: 'space-between'},
493
+ ]}>
494
+ <View
495
+ style={{flexDirection: 'row', alignItems: 'center', gap: 6}}>
496
+ <GlobeIcon color={AppColors.purple} size={14} />
497
+ <Text style={localStyles.sectionCardTitle}>
498
+ {t('crash.deviceEnvironment')}
499
+ </Text>
500
+ </View>
501
+ <CopyButton
502
+ value={
503
+ selectedCrash.deviceInfo || {
504
+ platform: Platform.OS,
505
+ osVersion: String(Platform.Version),
506
+ }
507
+ }
508
+ label="Diagnostics"
509
+ />
491
510
  </View>
492
511
 
493
512
  <View style={localStyles.diagGrid}>
@@ -538,9 +557,22 @@ const CrashDetail: React.FC = React.memo(() => {
538
557
  {/* Memory Metrics Card */}
539
558
  {selectedCrash.memoryInfo && (
540
559
  <View style={localStyles.sectionCard}>
541
- <View style={localStyles.sectionCardHeader}>
542
- <LayersIcon color={AppColors.purple} size={14} />
543
- <Text style={localStyles.sectionCardTitle}>{t('crash.jsHeapMemory')}</Text>
560
+ <View
561
+ style={[
562
+ localStyles.sectionCardHeader,
563
+ {justifyContent: 'space-between'},
564
+ ]}>
565
+ <View
566
+ style={{flexDirection: 'row', alignItems: 'center', gap: 6}}>
567
+ <LayersIcon color={AppColors.purple} size={14} />
568
+ <Text style={localStyles.sectionCardTitle}>
569
+ {t('crash.jsHeapMemory')}
570
+ </Text>
571
+ </View>
572
+ <CopyButton
573
+ value={selectedCrash.memoryInfo}
574
+ label="Memory Info"
575
+ />
544
576
  </View>
545
577
 
546
578
  <View style={localStyles.diagGrid}>
@@ -566,6 +598,19 @@ const CrashDetail: React.FC = React.memo(() => {
566
598
  {/* 3. BREADCRUMBS TAB */}
567
599
  {activeSubTab === 'breadcrumbs' && (
568
600
  <View style={{gap: 10}}>
601
+ {selectedCrash.breadcrumbs && selectedCrash.breadcrumbs.length > 0 && (
602
+ <View
603
+ style={{
604
+ flexDirection: 'row',
605
+ justifyContent: 'flex-end',
606
+ marginBottom: 2,
607
+ }}>
608
+ <CopyButton
609
+ value={selectedCrash.breadcrumbs}
610
+ label="All Breadcrumbs"
611
+ />
612
+ </View>
613
+ )}
569
614
  {selectedCrash.breadcrumbs && selectedCrash.breadcrumbs.length > 0 ? (
570
615
  selectedCrash.breadcrumbs.map((b, idx) => (
571
616
  <View key={`crumb_${idx}`} style={localStyles.breadcrumbCard}>
@@ -575,9 +620,20 @@ const CrashDetail: React.FC = React.memo(() => {
575
620
  {b.type.toUpperCase()}
576
621
  </Text>
577
622
  </View>
578
- <Text style={localStyles.breadcrumbTime}>
579
- {new Date(b.timestamp).toLocaleTimeString()}
580
- </Text>
623
+ <View
624
+ style={{
625
+ flexDirection: 'row',
626
+ alignItems: 'center',
627
+ gap: 8,
628
+ }}>
629
+ <Text style={localStyles.breadcrumbTime}>
630
+ {new Date(b.timestamp).toLocaleTimeString()}
631
+ </Text>
632
+ <CopyButton
633
+ value={`${new Date(b.timestamp).toLocaleTimeString()} [${b.type.toUpperCase()}] ${b.message}${b.data ? ' ' + JSON.stringify(b.data) : ''}`}
634
+ label="Breadcrumb"
635
+ />
636
+ </View>
581
637
  </View>
582
638
  <Text style={localStyles.breadcrumbMessage}>{b.message}</Text>
583
639
  {b.data && (