reactoradar 1.2.5 → 1.4.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.
- package/README.md +103 -223
- package/app.js +401 -70
- package/assets/icon.svg +283 -38
- package/index.html +5 -1
- package/main.js +9 -17
- package/package.json +1 -1
- package/preload.js +1 -1
- package/sdk/RNDebugSDK.js +117 -4
- package/styles.css +216 -13
package/assets/icon.svg
CHANGED
|
@@ -1,54 +1,299 @@
|
|
|
1
|
-
<svg
|
|
2
|
-
<title style="fill:rgb(0, 0, 0);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto">RN Debugger icon — version 2</title>
|
|
3
|
-
<desc style="fill:rgb(0, 0, 0);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto">Bold minimal macOS icon: deep navy rounded square, cyan React atom overlaid with a sharp red breakpoint dot. Clean and readable at any size.</desc>
|
|
4
|
-
|
|
1
|
+
<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
|
|
5
2
|
<defs>
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
<stop offset="
|
|
3
|
+
<!-- Background: deep space navy to near-black -->
|
|
4
|
+
<radialGradient id="bg" cx="50%" cy="42%" r="72%">
|
|
5
|
+
<stop offset="0%" stop-color="#081428"/>
|
|
6
|
+
<stop offset="50%" stop-color="#040a14"/>
|
|
7
|
+
<stop offset="100%" stop-color="#010306"/>
|
|
8
|
+
</radialGradient>
|
|
9
|
+
|
|
10
|
+
<!-- Radar disc fill -->
|
|
11
|
+
<radialGradient id="radarFill" cx="50%" cy="50%" r="50%">
|
|
12
|
+
<stop offset="0%" stop-color="#002b1a"/>
|
|
13
|
+
<stop offset="60%" stop-color="#001208"/>
|
|
14
|
+
<stop offset="100%" stop-color="#000704"/>
|
|
15
|
+
</radialGradient>
|
|
16
|
+
|
|
17
|
+
<!-- Radar soft glow -->
|
|
18
|
+
<radialGradient id="radarGlow" cx="50%" cy="50%" r="50%">
|
|
19
|
+
<stop offset="0%" stop-color="#00ff66" stop-opacity="0.14"/>
|
|
20
|
+
<stop offset="55%" stop-color="#00cc44" stop-opacity="0.05"/>
|
|
21
|
+
<stop offset="100%" stop-color="#00ff44" stop-opacity="0"/>
|
|
22
|
+
</radialGradient>
|
|
23
|
+
|
|
24
|
+
<!-- Center ambient warm green light -->
|
|
25
|
+
<radialGradient id="centerLight" cx="50%" cy="50%" r="50%">
|
|
26
|
+
<stop offset="0%" stop-color="#003d20" stop-opacity="0.7"/>
|
|
27
|
+
<stop offset="100%" stop-color="#000000" stop-opacity="0"/>
|
|
28
|
+
</radialGradient>
|
|
29
|
+
|
|
30
|
+
<!-- Sweep wedge gradient -->
|
|
31
|
+
<linearGradient id="sweepGrad" x1="1" y1="0" x2="0" y2="0" gradientUnits="userSpaceOnUse">
|
|
32
|
+
<stop offset="0%" stop-color="#00ff66" stop-opacity="0"/>
|
|
33
|
+
<stop offset="100%" stop-color="#00ff66" stop-opacity="0.18"/>
|
|
9
34
|
</linearGradient>
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
35
|
+
|
|
36
|
+
<!-- React orbit gradient: brighter, more cyan-electric -->
|
|
37
|
+
<linearGradient id="orbitGrad" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
38
|
+
<stop offset="0%" stop-color="#e0f8ff"/>
|
|
39
|
+
<stop offset="35%" stop-color="#61dafb"/>
|
|
40
|
+
<stop offset="100%" stop-color="#0e8ec9"/>
|
|
13
41
|
</linearGradient>
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
42
|
+
|
|
43
|
+
<!-- Nucleus sphere gradient -->
|
|
44
|
+
<radialGradient id="nucleusGrad" cx="35%" cy="28%" r="75%">
|
|
45
|
+
<stop offset="0%" stop-color="#ffffff"/>
|
|
46
|
+
<stop offset="25%" stop-color="#c8f0ff"/>
|
|
47
|
+
<stop offset="60%" stop-color="#2db8f0"/>
|
|
48
|
+
<stop offset="100%" stop-color="#0466a8"/>
|
|
49
|
+
</radialGradient>
|
|
50
|
+
|
|
51
|
+
<!-- Nucleus inner shine -->
|
|
52
|
+
<radialGradient id="nucleusShine" cx="30%" cy="25%" r="60%">
|
|
53
|
+
<stop offset="0%" stop-color="#ffffff" stop-opacity="0.95"/>
|
|
54
|
+
<stop offset="100%" stop-color="#44aaff" stop-opacity="0"/>
|
|
55
|
+
</radialGradient>
|
|
56
|
+
|
|
57
|
+
<!-- Top glass shine -->
|
|
58
|
+
<linearGradient id="glassShine" x1="0%" y1="0%" x2="0%" y2="100%">
|
|
59
|
+
<stop offset="0%" stop-color="#ffffff" stop-opacity="0.11"/>
|
|
60
|
+
<stop offset="100%" stop-color="#ffffff" stop-opacity="0"/>
|
|
17
61
|
</linearGradient>
|
|
62
|
+
|
|
63
|
+
<!-- Outer ring border gradient -->
|
|
64
|
+
<linearGradient id="borderGrad" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
65
|
+
<stop offset="0%" stop-color="#2a8acc" stop-opacity="0.7"/>
|
|
66
|
+
<stop offset="50%" stop-color="#0d4466" stop-opacity="0.4"/>
|
|
67
|
+
<stop offset="100%" stop-color="#1a5c99" stop-opacity="0.6"/>
|
|
68
|
+
</linearGradient>
|
|
69
|
+
|
|
70
|
+
<!-- Vignette -->
|
|
71
|
+
<radialGradient id="vignette" cx="50%" cy="50%" r="55%">
|
|
72
|
+
<stop offset="45%" stop-color="#000000" stop-opacity="0"/>
|
|
73
|
+
<stop offset="100%" stop-color="#000000" stop-opacity="0.85"/>
|
|
74
|
+
</radialGradient>
|
|
75
|
+
|
|
76
|
+
<!-- Debug bracket accent: warm amber -->
|
|
77
|
+
<linearGradient id="bugGrad" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
78
|
+
<stop offset="0%" stop-color="#ffcc44"/>
|
|
79
|
+
<stop offset="100%" stop-color="#ff8822"/>
|
|
80
|
+
</linearGradient>
|
|
81
|
+
|
|
82
|
+
<!-- Blip glow filter -->
|
|
83
|
+
<filter id="fBlip" x="-150%" y="-150%" width="400%" height="400%">
|
|
84
|
+
<feGaussianBlur stdDeviation="12" result="b"/>
|
|
85
|
+
<feMerge><feMergeNode in="b"/><feMergeNode in="SourceGraphic"/></feMerge>
|
|
86
|
+
</filter>
|
|
87
|
+
|
|
88
|
+
<!-- Orbit glow -->
|
|
89
|
+
<filter id="fOrbitGlow" x="-25%" y="-25%" width="150%" height="150%">
|
|
90
|
+
<feGaussianBlur stdDeviation="6" result="b"/>
|
|
91
|
+
<feMerge><feMergeNode in="b"/><feMergeNode in="SourceGraphic"/></feMerge>
|
|
92
|
+
</filter>
|
|
93
|
+
|
|
94
|
+
<!-- Atom crisp glow -->
|
|
95
|
+
<filter id="fAtom" x="-45%" y="-45%" width="190%" height="190%">
|
|
96
|
+
<feGaussianBlur stdDeviation="7" result="b"/>
|
|
97
|
+
<feMerge><feMergeNode in="b"/><feMergeNode in="SourceGraphic"/></feMerge>
|
|
98
|
+
</filter>
|
|
99
|
+
|
|
100
|
+
<!-- Nucleus deep glow -->
|
|
101
|
+
<filter id="fNucleus" x="-90%" y="-90%" width="280%" height="280%">
|
|
102
|
+
<feGaussianBlur stdDeviation="16" result="b"/>
|
|
103
|
+
<feMerge><feMergeNode in="b"/><feMergeNode in="SourceGraphic"/></feMerge>
|
|
104
|
+
</filter>
|
|
105
|
+
|
|
106
|
+
<!-- Sweep line glow -->
|
|
107
|
+
<filter id="fSweep" x="-15%" y="-15%" width="130%" height="130%">
|
|
108
|
+
<feGaussianBlur stdDeviation="10" result="b"/>
|
|
109
|
+
<feMerge><feMergeNode in="b"/><feMergeNode in="SourceGraphic"/></feMerge>
|
|
110
|
+
</filter>
|
|
111
|
+
|
|
112
|
+
<!-- Debug badge glow -->
|
|
113
|
+
<filter id="fBug" x="-50%" y="-50%" width="200%" height="200%">
|
|
114
|
+
<feGaussianBlur stdDeviation="8" result="b"/>
|
|
115
|
+
<feMerge><feMergeNode in="b"/><feMergeNode in="SourceGraphic"/></feMerge>
|
|
116
|
+
</filter>
|
|
117
|
+
|
|
118
|
+
<!-- Rounded icon clip -->
|
|
119
|
+
<clipPath id="iconClip">
|
|
120
|
+
<rect x="0" y="0" width="1024" height="1024" rx="224"/>
|
|
121
|
+
</clipPath>
|
|
18
122
|
</defs>
|
|
19
123
|
|
|
20
|
-
|
|
21
|
-
<rect x="40" y="40" width="600" height="600" rx="130" fill="url(#bg2)" style="stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:"Anthropic Sans", -apple-system, "system-ui", "Segoe UI", sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
|
|
124
|
+
<g clip-path="url(#iconClip)">
|
|
22
125
|
|
|
23
|
-
|
|
24
|
-
|
|
126
|
+
<!-- ── BACKGROUND ── -->
|
|
127
|
+
<rect width="1024" height="1024" fill="url(#bg)"/>
|
|
25
128
|
|
|
26
|
-
|
|
27
|
-
|
|
129
|
+
<!-- Subtle star field -->
|
|
130
|
+
<g fill="white">
|
|
131
|
+
<circle cx="80" cy="62" r="1.4" opacity="0.45"/>
|
|
132
|
+
<circle cx="210" cy="130" r="0.9" opacity="0.3"/>
|
|
133
|
+
<circle cx="875" cy="85" r="1.8" opacity="0.38"/>
|
|
134
|
+
<circle cx="948" cy="258" r="1.1" opacity="0.28"/>
|
|
135
|
+
<circle cx="48" cy="378" r="1.3" opacity="0.28"/>
|
|
136
|
+
<circle cx="988" cy="500" r="0.9" opacity="0.22"/>
|
|
137
|
+
<circle cx="124" cy="825" r="1.4" opacity="0.25"/>
|
|
138
|
+
<circle cx="912" cy="778" r="0.9" opacity="0.20"/>
|
|
139
|
+
<circle cx="750" cy="956" r="1.4" opacity="0.18"/>
|
|
140
|
+
<circle cx="345" cy="35" r="0.9" opacity="0.38"/>
|
|
141
|
+
<circle cx="595" cy="985" r="0.9" opacity="0.16"/>
|
|
142
|
+
<circle cx="175" cy="505" r="0.9" opacity="0.16"/>
|
|
143
|
+
<circle cx="828" cy="442" r="1.1" opacity="0.18"/>
|
|
144
|
+
<circle cx="430" cy="920" r="1.0" opacity="0.14"/>
|
|
145
|
+
<circle cx="65" cy="640" r="1.0" opacity="0.20"/>
|
|
146
|
+
<circle cx="960" cy="140" r="1.2" opacity="0.22"/>
|
|
147
|
+
</g>
|
|
28
148
|
|
|
29
|
-
<!--
|
|
30
|
-
<
|
|
149
|
+
<!-- ── RADAR DISC ── -->
|
|
150
|
+
<circle cx="512" cy="512" r="475" fill="url(#radarFill)"/>
|
|
151
|
+
<circle cx="512" cy="512" r="475" fill="url(#radarGlow)"/>
|
|
152
|
+
<circle cx="512" cy="512" r="270" fill="url(#centerLight)"/>
|
|
31
153
|
|
|
32
|
-
<!--
|
|
33
|
-
<
|
|
154
|
+
<!-- ── RADAR RINGS (concentric, getting brighter toward center) ── -->
|
|
155
|
+
<g transform="translate(512,512)" fill="none">
|
|
156
|
+
<circle r="455" stroke="#00ee55" stroke-width="1" opacity="0.12"/>
|
|
157
|
+
<circle r="364" stroke="#00ee55" stroke-width="1.2" opacity="0.18"/>
|
|
158
|
+
<circle r="273" stroke="#00ee55" stroke-width="1.5" opacity="0.26"/>
|
|
159
|
+
<circle r="182" stroke="#00ee55" stroke-width="1.8" opacity="0.36"/>
|
|
160
|
+
<circle r="91" stroke="#00ee55" stroke-width="2" opacity="0.50"/>
|
|
161
|
+
<circle r="38" stroke="#00ff66" stroke-width="2.2" opacity="0.65"/>
|
|
162
|
+
</g>
|
|
34
163
|
|
|
35
|
-
<!--
|
|
36
|
-
<
|
|
164
|
+
<!-- ── RADAR GRID LINES ── -->
|
|
165
|
+
<g stroke="#00cc44" stroke-width="1" opacity="0.15" fill="none">
|
|
166
|
+
<line x1="512" y1="37" x2="512" y2="987"/>
|
|
167
|
+
<line x1="37" y1="512" x2="987" y2="512"/>
|
|
168
|
+
<line x1="188" y1="188" x2="836" y2="836"/>
|
|
169
|
+
<line x1="836" y1="188" x2="188" y2="836"/>
|
|
170
|
+
</g>
|
|
37
171
|
|
|
38
|
-
<!--
|
|
39
|
-
<
|
|
40
|
-
|
|
172
|
+
<!-- ── SWEEP TRAIL WEDGE (pointing NE ~45°) ── -->
|
|
173
|
+
<g transform="translate(512,512)">
|
|
174
|
+
<!-- broad fading cone -->
|
|
175
|
+
<path d="M0,0 L455,0 A455,455 0 0,0 392,-221 Z"
|
|
176
|
+
fill="#00ff55" opacity="0.04"/>
|
|
177
|
+
<!-- tighter leading edge glow -->
|
|
178
|
+
<path d="M0,0 L428,-160 A455,455 0 0,0 455,0 Z"
|
|
179
|
+
fill="#00ff55" opacity="0.03"/>
|
|
180
|
+
<!-- extra thin wedge for depth -->
|
|
181
|
+
<path d="M0,0 L455,0 A455,455 0 0,0 455,-60 Z"
|
|
182
|
+
fill="#00ff88" opacity="0.025"/>
|
|
183
|
+
</g>
|
|
41
184
|
|
|
42
|
-
|
|
185
|
+
<!-- ── SWEEP LINE ── -->
|
|
186
|
+
<g filter="url(#fSweep)">
|
|
187
|
+
<!-- Outer soft glow layer -->
|
|
188
|
+
<line x1="512" y1="512" x2="923" y2="141"
|
|
189
|
+
stroke="#66ff22" stroke-width="10" stroke-linecap="round" opacity="0.38"/>
|
|
190
|
+
<!-- Mid bright -->
|
|
191
|
+
<line x1="512" y1="512" x2="923" y2="141"
|
|
192
|
+
stroke="#ccff55" stroke-width="4" stroke-linecap="round" opacity="0.88"/>
|
|
193
|
+
<!-- White hot core -->
|
|
194
|
+
<line x1="512" y1="512" x2="923" y2="141"
|
|
195
|
+
stroke="#ffffff" stroke-width="1.8" stroke-linecap="round" opacity="0.55"/>
|
|
196
|
+
</g>
|
|
197
|
+
|
|
198
|
+
<!-- ── RADAR BLIPS ── -->
|
|
199
|
+
<g filter="url(#fBlip)">
|
|
200
|
+
<!-- Main bright blip (largest, just past first ring) -->
|
|
201
|
+
<circle cx="726" cy="305" r="11" fill="#00ff66" opacity="1.0"/>
|
|
202
|
+
<circle cx="726" cy="305" r="28" fill="#00ff66" opacity="0.18"/>
|
|
203
|
+
<!-- Secondary blip -->
|
|
204
|
+
<circle cx="655" cy="438" r="7.5" fill="#44ff88" opacity="0.92"/>
|
|
205
|
+
<circle cx="655" cy="438" r="18" fill="#44ff88" opacity="0.14"/>
|
|
206
|
+
<!-- Faint distant blips -->
|
|
207
|
+
<circle cx="795" cy="396" r="5.5" fill="#00dd44" opacity="0.55"/>
|
|
208
|
+
<circle cx="845" cy="265" r="4.5" fill="#88ffaa" opacity="0.42"/>
|
|
209
|
+
<circle cx="562" cy="328" r="3.5" fill="#00cc44" opacity="0.35"/>
|
|
210
|
+
<!-- Extra blip bottom-left quadrant (more scan coverage) -->
|
|
211
|
+
<circle cx="368" cy="640" r="5" fill="#22ff77" opacity="0.38"/>
|
|
212
|
+
<circle cx="310" cy="560" r="3" fill="#00ee55" opacity="0.28"/>
|
|
213
|
+
</g>
|
|
214
|
+
|
|
215
|
+
<!-- ── CENTER PIP ── -->
|
|
216
|
+
<circle cx="512" cy="512" r="12" fill="#00ff55" opacity="0.95" filter="url(#fBlip)"/>
|
|
217
|
+
<circle cx="512" cy="512" r="5" fill="#ddfff0"/>
|
|
218
|
+
|
|
219
|
+
<!-- ── VIGNETTE ── -->
|
|
220
|
+
<rect width="1024" height="1024" fill="url(#vignette)"/>
|
|
221
|
+
|
|
222
|
+
<!-- ── REACT ATOM (centered, large) ── -->
|
|
223
|
+
<g transform="translate(512, 512)">
|
|
43
224
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
225
|
+
<!-- Orbit glow halos -->
|
|
226
|
+
<g filter="url(#fOrbitGlow)" opacity="0.5">
|
|
227
|
+
<ellipse cx="0" cy="0" rx="275" ry="97" fill="none"
|
|
228
|
+
stroke="#61dafb" stroke-width="20"/>
|
|
229
|
+
<ellipse cx="0" cy="0" rx="275" ry="97" fill="none"
|
|
230
|
+
stroke="#61dafb" stroke-width="20" transform="rotate(60)"/>
|
|
231
|
+
<ellipse cx="0" cy="0" rx="275" ry="97" fill="none"
|
|
232
|
+
stroke="#61dafb" stroke-width="20" transform="rotate(120)"/>
|
|
233
|
+
</g>
|
|
50
234
|
|
|
51
|
-
|
|
52
|
-
|
|
235
|
+
<!-- Orbit rings — crisp -->
|
|
236
|
+
<g filter="url(#fAtom)">
|
|
237
|
+
<ellipse cx="0" cy="0" rx="275" ry="97" fill="none"
|
|
238
|
+
stroke="url(#orbitGrad)" stroke-width="14" opacity="0.95"/>
|
|
239
|
+
<ellipse cx="0" cy="0" rx="275" ry="97" fill="none"
|
|
240
|
+
stroke="url(#orbitGrad)" stroke-width="14" opacity="0.95"
|
|
241
|
+
transform="rotate(60)"/>
|
|
242
|
+
<ellipse cx="0" cy="0" rx="275" ry="97" fill="none"
|
|
243
|
+
stroke="url(#orbitGrad)" stroke-width="14" opacity="0.95"
|
|
244
|
+
transform="rotate(120)"/>
|
|
245
|
+
</g>
|
|
53
246
|
|
|
54
|
-
|
|
247
|
+
<!-- Nucleus corona layers -->
|
|
248
|
+
<circle cx="0" cy="0" r="92" fill="#1166cc" opacity="0.16" filter="url(#fNucleus)"/>
|
|
249
|
+
<circle cx="0" cy="0" r="70" fill="#2288ee" opacity="0.20"/>
|
|
250
|
+
<circle cx="0" cy="0" r="54" fill="#1a77dd" opacity="0.32"/>
|
|
251
|
+
|
|
252
|
+
<!-- Nucleus main sphere -->
|
|
253
|
+
<circle cx="0" cy="0" r="48" fill="url(#nucleusGrad)"/>
|
|
254
|
+
|
|
255
|
+
<!-- Nucleus highlight spot -->
|
|
256
|
+
<circle cx="-11" cy="-14" r="20" fill="url(#nucleusShine)"/>
|
|
257
|
+
<circle cx="-12" cy="-15" r="9" fill="#ffffff" opacity="0.8"/>
|
|
258
|
+
|
|
259
|
+
</g>
|
|
260
|
+
|
|
261
|
+
<!-- ── DEBUG BADGE — bottom-right corner ── -->
|
|
262
|
+
<!-- Subtle "{}" debug symbol as a badge, amber/orange to signal "debugger" -->
|
|
263
|
+
<g transform="translate(780, 782)" filter="url(#fBug)">
|
|
264
|
+
<!-- Badge circle -->
|
|
265
|
+
<circle cx="0" cy="0" r="88" fill="#0d1e0e" opacity="0.92"/>
|
|
266
|
+
<circle cx="0" cy="0" r="88" fill="none" stroke="url(#bugGrad)" stroke-width="5" opacity="0.9"/>
|
|
267
|
+
<!-- Bug icon: stylized beetle/bug shape -->
|
|
268
|
+
<!-- Body ellipse -->
|
|
269
|
+
<ellipse cx="0" cy="6" rx="26" ry="34" fill="url(#bugGrad)" opacity="0.95"/>
|
|
270
|
+
<!-- Head -->
|
|
271
|
+
<circle cx="0" cy="-30" r="16" fill="url(#bugGrad)" opacity="0.95"/>
|
|
272
|
+
<!-- Antennae -->
|
|
273
|
+
<line x1="-8" y1="-42" x2="-22" y2="-62" stroke="#ffcc44" stroke-width="3.5" stroke-linecap="round" opacity="0.9"/>
|
|
274
|
+
<line x1="8" y1="-42" x2="22" y2="-62" stroke="#ffcc44" stroke-width="3.5" stroke-linecap="round" opacity="0.9"/>
|
|
275
|
+
<circle cx="-22" cy="-62" r="4" fill="#ffee88" opacity="0.85"/>
|
|
276
|
+
<circle cx="22" cy="-62" r="4" fill="#ffee88" opacity="0.85"/>
|
|
277
|
+
<!-- Legs left -->
|
|
278
|
+
<line x1="-26" y1="-8" x2="-52" y2="-18" stroke="#ff9933" stroke-width="3" stroke-linecap="round" opacity="0.85"/>
|
|
279
|
+
<line x1="-26" y1="6" x2="-54" y2="6" stroke="#ff9933" stroke-width="3" stroke-linecap="round" opacity="0.85"/>
|
|
280
|
+
<line x1="-26" y1="20" x2="-50" y2="30" stroke="#ff9933" stroke-width="3" stroke-linecap="round" opacity="0.85"/>
|
|
281
|
+
<!-- Legs right -->
|
|
282
|
+
<line x1="26" y1="-8" x2="52" y2="-18" stroke="#ff9933" stroke-width="3" stroke-linecap="round" opacity="0.85"/>
|
|
283
|
+
<line x1="26" y1="6" x2="54" y2="6" stroke="#ff9933" stroke-width="3" stroke-linecap="round" opacity="0.85"/>
|
|
284
|
+
<line x1="26" y1="20" x2="50" y2="30" stroke="#ff9933" stroke-width="3" stroke-linecap="round" opacity="0.85"/>
|
|
285
|
+
<!-- Wing split line -->
|
|
286
|
+
<line x1="0" y1="-10" x2="0" y2="36" stroke="#ffcc44" stroke-width="2" stroke-linecap="round" opacity="0.5"/>
|
|
287
|
+
</g>
|
|
288
|
+
|
|
289
|
+
<!-- ── GLASS SHINE (top half) ── -->
|
|
290
|
+
<rect width="1024" height="470" fill="url(#glassShine)"/>
|
|
291
|
+
|
|
292
|
+
<!-- ── ICON BORDER ── -->
|
|
293
|
+
<rect x="0" y="0" width="1024" height="1024" rx="224"
|
|
294
|
+
fill="none" stroke="url(#borderGrad)" stroke-width="6" opacity="0.55"/>
|
|
295
|
+
<rect x="7" y="7" width="1010" height="1010" rx="218"
|
|
296
|
+
fill="none" stroke="#ffffff" stroke-width="2" opacity="0.06"/>
|
|
297
|
+
|
|
298
|
+
</g>
|
|
299
|
+
</svg>
|
package/index.html
CHANGED
|
@@ -21,7 +21,6 @@
|
|
|
21
21
|
<span id="deviceText">Waiting for device...</span>
|
|
22
22
|
</div>
|
|
23
23
|
<div class="titlebar-actions">
|
|
24
|
-
<button class="tb-btn" id="btnClear" title="Clear active tab (⌘K clears all)">Clear</button>
|
|
25
24
|
<button class="tb-btn primary" id="btnCDP" title="Open JS Debugger (⌘D)">JS Debugger ↗</button>
|
|
26
25
|
</div>
|
|
27
26
|
</header>
|
|
@@ -40,6 +39,10 @@
|
|
|
40
39
|
<svg viewBox="0 0 20 20"><rect x="3" y="3" width="6" height="6" rx="1" stroke="currentColor" stroke-width="1.5" fill="none"/><rect x="11" y="3" width="6" height="6" rx="1" stroke="currentColor" stroke-width="1.5" fill="none"/><rect x="7" y="11" width="6" height="6" rx="1" stroke="currentColor" stroke-width="1.5" fill="none"/></svg>
|
|
41
40
|
<span>Redux</span>
|
|
42
41
|
</button>
|
|
42
|
+
<button class="nav-btn" data-panel="ga4" title="GA4 Events">
|
|
43
|
+
<svg viewBox="0 0 20 20"><path d="M10 2v16M6 6l4-4 4 4M3 18h14" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" fill="none"/><circle cx="5" cy="13" r="2" stroke="currentColor" stroke-width="1.2" fill="none"/><circle cx="10" cy="9" r="2" stroke="currentColor" stroke-width="1.2" fill="none"/><circle cx="15" cy="12" r="2" stroke="currentColor" stroke-width="1.2" fill="none"/></svg>
|
|
44
|
+
<span>GA4</span>
|
|
45
|
+
</button>
|
|
43
46
|
<button class="nav-btn" data-panel="storage" title="Application">
|
|
44
47
|
<svg viewBox="0 0 20 20"><ellipse cx="10" cy="6" rx="7" ry="3" stroke="currentColor" stroke-width="1.5" fill="none"/><path d="M3 6v4c0 1.66 3.13 3 7 3s7-1.34 7-3V6" stroke="currentColor" stroke-width="1.5" fill="none"/><path d="M3 10v4c0 1.66 3.13 3 7 3s7-1.34 7-3v-4" stroke="currentColor" stroke-width="1.5" fill="none"/></svg>
|
|
45
48
|
<span>App</span>
|
|
@@ -69,6 +72,7 @@
|
|
|
69
72
|
<div id="panel-network" class="panel"></div>
|
|
70
73
|
<div id="panel-performance" class="panel"></div>
|
|
71
74
|
<div id="panel-memory" class="panel"></div>
|
|
75
|
+
<div id="panel-ga4" class="panel"></div>
|
|
72
76
|
<div id="panel-redux" class="panel"></div>
|
|
73
77
|
<div id="panel-storage" class="panel"></div>
|
|
74
78
|
<div id="panel-react" class="panel"></div>
|
package/main.js
CHANGED
|
@@ -24,26 +24,16 @@ let reduxClients = new Set();
|
|
|
24
24
|
let storageClients = new Set();
|
|
25
25
|
let networkClients = new Set();
|
|
26
26
|
|
|
27
|
+
// ─── Set dock icon ASAP (before app ready) ──────────────────────────────────
|
|
28
|
+
const _appIcon = nativeImage.createFromPath(path.join(__dirname, 'ReactoRadar.png'));
|
|
29
|
+
|
|
27
30
|
// ─── App lifecycle ────────────────────────────────────────────────────────────
|
|
28
31
|
app.whenReady().then(async () => {
|
|
29
|
-
// Theme will be set by renderer via IPC once it reads localStorage
|
|
30
32
|
nativeTheme.themeSource = 'dark';
|
|
31
33
|
|
|
32
|
-
// Set dock icon on macOS
|
|
33
|
-
if (process.platform === 'darwin') {
|
|
34
|
-
try {
|
|
35
|
-
const icnsPath = path.join(__dirname, 'ReactoRadar.icns');
|
|
36
|
-
const pngPath = path.join(__dirname, 'ReactoRadar.png');
|
|
37
|
-
const fs = require('fs');
|
|
38
|
-
// Prefer .icns (handles dock scaling correctly), fallback to .png
|
|
39
|
-
const iconPath = fs.existsSync(icnsPath) ? icnsPath : pngPath;
|
|
40
|
-
const icon = nativeImage.createFromPath(iconPath);
|
|
41
|
-
if (!icon.isEmpty()) {
|
|
42
|
-
app.dock.setIcon(icon);
|
|
43
|
-
}
|
|
44
|
-
} catch (e) {
|
|
45
|
-
console.warn('[Icon] Failed to set dock icon:', e.message);
|
|
46
|
-
}
|
|
34
|
+
// Set dock icon on macOS
|
|
35
|
+
if (process.platform === 'darwin' && !_appIcon.isEmpty()) {
|
|
36
|
+
try { app.dock.setIcon(_appIcon); } catch {}
|
|
47
37
|
}
|
|
48
38
|
|
|
49
39
|
await createMainWindow();
|
|
@@ -96,7 +86,7 @@ async function createMainWindow() {
|
|
|
96
86
|
contextIsolation: true,
|
|
97
87
|
preload: path.join(__dirname, 'preload.js'),
|
|
98
88
|
},
|
|
99
|
-
icon:
|
|
89
|
+
icon: _appIcon,
|
|
100
90
|
});
|
|
101
91
|
|
|
102
92
|
mainWindow.loadFile(path.join(__dirname, 'index.html'));
|
|
@@ -267,6 +257,8 @@ function startBridgeServers() {
|
|
|
267
257
|
mainWindow?.webContents.send('console-event', event);
|
|
268
258
|
} else if (event.type === 'perf') {
|
|
269
259
|
mainWindow?.webContents.send('perf-event', event);
|
|
260
|
+
} else if (event.type === 'ga4') {
|
|
261
|
+
mainWindow?.webContents.send('ga4-event', event);
|
|
270
262
|
} else {
|
|
271
263
|
mainWindow?.webContents.send('network-event', event);
|
|
272
264
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "reactoradar",
|
|
3
3
|
"productName": "ReactoRadar",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.4.1",
|
|
5
5
|
"description": "macOS debugger for React Native — Console, Sources, Network, Performance, Memory, Redux, AsyncStorage, React tree. Supports RN 0.74+ with Hermes and New Architecture.",
|
|
6
6
|
"main": "main.js",
|
|
7
7
|
"bin": {
|
package/preload.js
CHANGED
|
@@ -9,7 +9,7 @@ contextBridge.exposeInMainWorld('electronAPI', {
|
|
|
9
9
|
on: (channel, cb) => {
|
|
10
10
|
const allowed = [
|
|
11
11
|
'ports', 'cdp-targets', 'redux-event', 'storage-event', 'network-event',
|
|
12
|
-
'console-event', 'perf-event', 'redux-connected', 'storage-connected', 'network-connected',
|
|
12
|
+
'console-event', 'perf-event', 'ga4-event', 'redux-connected', 'storage-connected', 'network-connected',
|
|
13
13
|
'react-dt-status', 'trigger-open-cdp', 'clear-all-ui', 'theme-changed', 'update-available', 'app-version',
|
|
14
14
|
];
|
|
15
15
|
if (allowed.includes(channel)) {
|
package/sdk/RNDebugSDK.js
CHANGED
|
@@ -529,10 +529,123 @@ try {
|
|
|
529
529
|
}, 2000);
|
|
530
530
|
})();
|
|
531
531
|
|
|
532
|
-
//
|
|
533
|
-
//
|
|
534
|
-
//
|
|
535
|
-
//
|
|
532
|
+
// ─── GA4 / Firebase Analytics Interceptor ────────────────────────────────────
|
|
533
|
+
// Intercepts @react-native-firebase/analytics logEvent calls.
|
|
534
|
+
// The analytics() function returns a new instance each time, so we patch the
|
|
535
|
+
// PROTOTYPE of the analytics module class, not individual instances.
|
|
536
|
+
(function setupGA4Interceptor() {
|
|
537
|
+
function patchAnalytics() {
|
|
538
|
+
try {
|
|
539
|
+
const analyticsModule = require('@react-native-firebase/analytics');
|
|
540
|
+
if (!analyticsModule) return false;
|
|
541
|
+
|
|
542
|
+
// Get the default export (the analytics factory function)
|
|
543
|
+
const analyticsFn = analyticsModule.default || analyticsModule;
|
|
544
|
+
if (typeof analyticsFn !== 'function') return false;
|
|
545
|
+
|
|
546
|
+
// Create one instance to get access to its prototype
|
|
547
|
+
const instance = analyticsFn();
|
|
548
|
+
if (!instance || !instance.logEvent) return false;
|
|
549
|
+
|
|
550
|
+
const proto = Object.getPrototypeOf(instance);
|
|
551
|
+
if (!proto || proto.__reactoRadarPatched) return false;
|
|
552
|
+
proto.__reactoRadarPatched = true;
|
|
553
|
+
|
|
554
|
+
// Helper to safely serialize params
|
|
555
|
+
function _safeParams(p) {
|
|
556
|
+
if (!p || typeof p !== 'object') return p || {};
|
|
557
|
+
try { return JSON.parse(JSON.stringify(p)); } catch { return {}; }
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
// Convert method name to event name: logAddToCart → add_to_cart
|
|
561
|
+
function _methodToEvent(name) {
|
|
562
|
+
// Remove 'log' prefix, then convert camelCase to snake_case
|
|
563
|
+
return name.replace(/^log/, '')
|
|
564
|
+
.replace(/([A-Z])/g, '_$1')
|
|
565
|
+
.toLowerCase()
|
|
566
|
+
.replace(/^_/, '');
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
// Dynamically wrap ALL methods that start with 'log' on the prototype
|
|
570
|
+
// This catches logEvent, logPurchase, logAddToCart, logScreenView, etc.
|
|
571
|
+
// Also catches any future methods Firebase adds.
|
|
572
|
+
Object.getOwnPropertyNames(proto).forEach(methodName => {
|
|
573
|
+
if (!methodName.startsWith('log') || typeof proto[methodName] !== 'function') return;
|
|
574
|
+
|
|
575
|
+
const orig = proto[methodName];
|
|
576
|
+
|
|
577
|
+
if (methodName === 'logEvent') {
|
|
578
|
+
// logEvent has signature: (eventName, params, options?)
|
|
579
|
+
proto.logEvent = function(eventName, params, options) {
|
|
580
|
+
try { mainCh.send({ type: 'ga4', name: eventName, params: _safeParams(params), tag: 'GA4' }); } catch {}
|
|
581
|
+
return orig.call(this, eventName, params, options);
|
|
582
|
+
};
|
|
583
|
+
} else {
|
|
584
|
+
// All other log methods: logPurchase(params), logScreenView(params), etc.
|
|
585
|
+
const eventName = _methodToEvent(methodName);
|
|
586
|
+
proto[methodName] = function() {
|
|
587
|
+
try {
|
|
588
|
+
// First argument is always the params object (or undefined for logAppOpen, logTutorialBegin, etc.)
|
|
589
|
+
const params = arguments[0];
|
|
590
|
+
mainCh.send({ type: 'ga4', name: eventName, params: _safeParams(params), tag: 'GA4' });
|
|
591
|
+
} catch {}
|
|
592
|
+
return orig.apply(this, arguments);
|
|
593
|
+
};
|
|
594
|
+
}
|
|
595
|
+
});
|
|
596
|
+
|
|
597
|
+
// Also wrap set* methods to track user properties/consent
|
|
598
|
+
['setUserId', 'setUserProperty', 'setUserProperties', 'setConsent', 'setDefaultEventParameters', 'setAnalyticsCollectionEnabled'].forEach(methodName => {
|
|
599
|
+
if (!proto[methodName] || typeof proto[methodName] !== 'function') return;
|
|
600
|
+
const orig = proto[methodName];
|
|
601
|
+
proto[methodName] = function() {
|
|
602
|
+
try {
|
|
603
|
+
const params = {};
|
|
604
|
+
// Capture the arguments as key-value
|
|
605
|
+
if (arguments.length === 1) params.value = _safeParams(arguments[0]);
|
|
606
|
+
else if (arguments.length >= 2) { params.name = arguments[0]; params.value = arguments[1]; }
|
|
607
|
+
mainCh.send({ type: 'ga4', name: methodName, params, tag: 'GA4' });
|
|
608
|
+
} catch {}
|
|
609
|
+
return orig.apply(this, arguments);
|
|
610
|
+
};
|
|
611
|
+
});
|
|
612
|
+
|
|
613
|
+
_console.log('[RNDebugSDK] GA4 Analytics prototype interceptor active');
|
|
614
|
+
return true;
|
|
615
|
+
} catch (e) {
|
|
616
|
+
return false;
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
// Try immediately, then retry at increasing delays
|
|
621
|
+
if (!patchAnalytics()) {
|
|
622
|
+
[100, 500, 2000, 5000].forEach(delay => {
|
|
623
|
+
setTimeout(() => patchAnalytics(), delay);
|
|
624
|
+
});
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
// Fallback: also patch the module's default export function to wrap returned instances
|
|
628
|
+
setTimeout(() => {
|
|
629
|
+
try {
|
|
630
|
+
const mod = require('@react-native-firebase/analytics');
|
|
631
|
+
if (!mod || mod.__reactoRadarWrapped) return;
|
|
632
|
+
const origDefault = mod.default;
|
|
633
|
+
if (typeof origDefault !== 'function') return;
|
|
634
|
+
mod.__reactoRadarWrapped = true;
|
|
635
|
+
mod.default = function() {
|
|
636
|
+
const inst = origDefault.apply(this, arguments);
|
|
637
|
+
// Ensure prototype is patched (in case new prototype was created)
|
|
638
|
+
if (inst && inst.logEvent) {
|
|
639
|
+
const p = Object.getPrototypeOf(inst);
|
|
640
|
+
if (p && !p.__reactoRadarPatched) patchAnalytics();
|
|
641
|
+
}
|
|
642
|
+
return inst;
|
|
643
|
+
};
|
|
644
|
+
// Copy static properties
|
|
645
|
+
Object.keys(origDefault).forEach(k => { mod.default[k] = origDefault[k]; });
|
|
646
|
+
} catch {}
|
|
647
|
+
}, 50);
|
|
648
|
+
})();
|
|
536
649
|
|
|
537
650
|
console.log(`[RNDebugSDK] Connected to ${HOST} | Console+Network:${PORTS.NETWORK_AND_CONSOLE} Redux:${PORTS.REDUX} Storage:${PORTS.STORAGE}`);
|
|
538
651
|
|