Skip to content

Commit e0ad021

Browse files
committed
merging mark's changes to hooks
2 parents d28a381 + 6312da1 commit e0ad021

File tree

5 files changed

+96
-35
lines changed

5 files changed

+96
-35
lines changed

src/app/components/StateRoute/ComponentMap/ComponentMap.tsx

Lines changed: 67 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
/* eslint-disable guard-for-in */
99
// @ts-nocheck
1010

11-
import React, { useState, useEffect } from 'react';
11+
import React, { useState, useEffect, useRef } from 'react';
1212
import { Group } from '@visx/group';
1313
import { hierarchy, Tree } from '@visx/hierarchy';
1414
import { LinearGradient } from '@visx/gradient';
@@ -47,9 +47,9 @@ export default function ComponentMap({
4747
const [orientation, setOrientation] = useState('vertical');
4848
const [linkType, setLinkType] = useState('diagonal');
4949
const [stepPercent, setStepPercent] = useState(10);
50-
const [Tooltip, setTooltip] = useState(false);
5150
const [selectedNode, setSelectedNode] = useState('root');
5251
const [, dispatch] = useStoreContext();
52+
const toolTipTimeoutID = useRef(null);
5353

5454
useEffect(() => {
5555
dispatch(setCurrentTabInApp('map'));
@@ -191,7 +191,6 @@ export default function ComponentMap({
191191
<LinearGradient id='links-gradient' from='#fd9b93' to='#fe6e9e' />
192192
<rect
193193
onClick={() => {
194-
setTooltip(false);
195194
hideTooltip();
196195
}}
197196
width={totalWidth}
@@ -266,7 +265,6 @@ export default function ComponentMap({
266265
onClick={() => {
267266
dispatch(toggleExpanded(node.data));
268267
hideTooltip();
269-
setTooltip(false);
270268
}}
271269
/>
272270
)}
@@ -290,16 +288,48 @@ export default function ComponentMap({
290288
onClick={() => {
291289
dispatch(toggleExpanded(node.data));
292290
hideTooltip();
293-
setTooltip(false);
294291
}}
295-
onMouseOver={(event) => {
296-
setTooltip(true);
292+
// Mouse Enter Rect (Component Node) -----------------------------------------------------------------------
293+
/** This onMouseEnter event fires when the mouse first moves/hovers over a component node.
294+
* The supplied event listener callback produces a Tooltip element for the current node. */
295+
296+
onMouseEnter={(event) => {
297+
/** This 'if' statement block checks to see if you've just left another component node
298+
* by seeing if there's a current setTimeout waiting to close that component node's
299+
* tooltip (see onMouseLeave immediately below).
300+
* This setTimeout gives the mouse time to enter the tooltip element so the tooltip
301+
* can persist. If instead of entering said tooltip element you've left the previous
302+
* component node to enter this component node, this logic will clear the timeout event,
303+
* and close the tooltip. */
304+
if (toolTipTimeoutID.current !== null) {
305+
clearTimeout(toolTipTimeoutID.current);
306+
hideTooltip();
307+
}
308+
/** The following line resets the toolTipTimeoutID.current to null, showing that there
309+
* are no current setTimeouts running. I placed this outside of the above if statement
310+
* to make sure there are no edge cases that would allow for the toolTipTimeoutID.current
311+
* to hold onto an old reference. */
312+
toolTipTimeoutID.current = null;
313+
//This generates a tooltip for the component node the mouse has entered.
297314
handleMouseAndClickOver(event);
298315
}}
299-
// with onmouseOver, this produces a hover over effect for the Tooltip
300-
onMouseOut={() => {
301-
hideTooltip();
302-
setTooltip(false);
316+
317+
// Mouse Leave Rect (Component Node) --------------------------------------------------------------------------
318+
/** This onMouseLeave event fires when the mouse leaves a component node.
319+
* The supplied event listener callback generates a setTimeout call which gives the
320+
* mouse a certain amount of time between leaving the current component node and
321+
* closing the tooltip for that node.
322+
* If the mouse enters the tooltip before the timeout delay has passed, the
323+
* setTimeout event will be canceled. */
324+
onMouseLeave={() => {
325+
// This line invokes setTimeout and saves its ID to the useRef var toolTipTimeoutID
326+
toolTipTimeoutID.current = setTimeout(() => {
327+
// hideTooltip unmounts the tooltip
328+
hideTooltip();
329+
// As the timeout has been executed, the timeoutID can be reset to null
330+
toolTipTimeoutID.current = null;
331+
//There is a delay of 300 ms
332+
}, 300);
303333
}}
304334
/>
305335
)}
@@ -329,33 +359,48 @@ export default function ComponentMap({
329359
top={tooltipTop}
330360
left={tooltipLeft}
331361
style={tooltipStyles}
332-
onClick={hideTooltip}
362+
363+
//------------- Mouse Over TooltipInPortal--------------------------------------------------------------------
364+
/** This onMouseEnter fires when the mouse first moves/hovers over the tooltip
365+
* The supplied event listener callback stops the setTimeout that was going to
366+
* close the tooltip from firing */
367+
368+
onMouseEnter={() => {
369+
// The setTimeoutID stored in toolTipTimeoutID.current is from the setTimeout initiated by leaving the
370+
// component node that generated the tooltip. If you've triggered an onMouseEnter event in that tooltip,
371+
clearTimeout(toolTipTimeoutID.current);
372+
// This line resets the timeoutID to null
373+
toolTipTimeoutID.current = null;
374+
}}
375+
376+
//------------- Mouse Leave TooltipInPortal -----------------------------------------------------------------
377+
/** This onMouseLeave event fires when the mouse leaves the tooltip
378+
* The supplied event listener callback unmounts the tooltip */
379+
onMouseLeave={() => {
380+
// hideTooltip unmounts the tooltip
381+
hideTooltip();
382+
}}
333383
>
334-
<div
335-
onClick={() => {
336-
setTooltip(false);
337-
hideTooltip();
338-
}}
339-
>
384+
<div>
340385
<div style={{}}>
341386
{' '}
342387
<strong>{tooltipData.name}</strong>{' '}
343388
</div>
344389
<div> Render time: {formatRenderTime(tooltipData.componentData.actualDuration)} </div>
345390
<div className='stateTip'>
346-
State:
347-
{formatState(tooltipData.state)}
391+
State: {formatState(tooltipData.state)}
348392
</div>
349393
<div style={React.scrollStyle}>
350394
<div className='tooltipWrapper'>
351395
<h2>Props:</h2>
352396
{formatData(tooltipData.componentData.props, 'props')}
353397
</div>
354-
398+
399+
{/* Currently no use for this field
355400
<div className='tooltipWrapper'>
356401
<h2>Initial Context:</h2>
357402
{formatData(tooltipData.componentData.context, 'context')}
358-
</div>
403+
</div> */}
359404

360405
<div className='tooltipWrapper'>
361406
<h2>State:</h2>

src/app/index.tsx

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,19 @@
11
/* eslint-disable react/jsx-filename-extension */
22
import React from 'react';
3-
import ReactDOM from 'react-dom';
3+
// import ReactDOM from 'react-dom';
4+
import { createRoot } from 'react-dom/client';
45
import App from './components/App';
56
import './styles/main.scss';
67

7-
ReactDOM.render(<App />, document.getElementById('root'));
8+
// Old way of rendering that was locking Reactime into React 17
9+
// Left for testing purposes
10+
// ReactDOM.render(<App />, document.getElementById('root'));
11+
12+
//New way of rendering that allows us to use React 18
13+
const root = createRoot(document.getElementById("root"));
14+
root.render(
15+
//Strict mode is for developers, it throws extra errors
16+
// <StrictMode>
17+
<App/>
18+
// </StrictMode>
19+
);

src/backend/controllers/statePropExtractors.ts

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -140,31 +140,35 @@ export function getHooksNames(elementType: string): { hookName: string; varName:
140140
// console.log('expression', declarations[0]?.init?.arguments?.arguments[0]?.callee?.expressions);
141141
const expression =
142142
declarations[0]?.init?.callee?.expressions || //work for browser
143-
(declarations[0]?.init?.arguments &&
144-
declarations[0]?.init?.arguments[0]?.callee?.expressions); //work for jest test; Mark's notes: so this was where the app was breaking. ES6 functions inside functional components were hitting this line and crashing when it tried to access arguments[0] and arguments didn't exist.
145-
// declarations[0]?.init?.arguments?.arguments[0]?.callee?.expressions; //work for jest test
143+
//Mark's notes: so this was where the app was breaking. ES6 functions (e.g. const handleClick = () => {}) inside functional components were hitting this line and crashing when it tried to access arguments[0] and arguments didn't exist.
144+
declarations[0]?.init?.arguments?.[0]?.callee?.expressions; //work for jest test;
146145

147-
// console.log('looked for expression, found:', expression);
148-
if (expression === undefined) return; //Mark's Note: for a functional definition that isn't a hook, it won't have the callee being searched for above. This line will cause this forEach execution to stop here in this case.
146+
console.log('looked for expression, found:', expression);
147+
//Mark's Note: for a functional definition that isn't a hook, it won't have the callee being searched for above. This line will cause this forEach execution to stop here in this case.
148+
if (expression === undefined) return;
149149
let reactHook: string;
150150
reactHook = expression[1].property?.name;
151151
if (reactHook === 'useState') {
152152
// Obtain the variable being set:
153+
//Mark's note: changed to point to second to last element of declarations because webpack adds an extra variable when converting files that use ES6, so the previous pointer wasn't working for this case
153154
let varName: string =
154-
declarations[declarations.length - 2]?.id?.name || // work react application; Mark's note: changed to point to second to last element of declarations because webpack added an extra variable and therefor declaration in the middle of the array cuz es6
155+
declarations[declarations.length - 2]?.id?.name || // work react application;
155156
(Array.isArray(declarations[0]?.id?.elements)
156157
? declarations[0]?.id?.elements[0]?.name
157158
: undefined); //work for nextJS application
158159
// Obtain the setState method:
160+
//Mark's note: changed to point to last element of declarations because webpack adds an extra variable when converting files that use ES6, so the previous pointer wasn't working for this case
159161
let hookName: string =
160-
declarations[declarations.length - 1]?.id?.name || // work react application; Mark's note: changed to point to last element of declarations because webpack added an extra variable and therefor declaration in the middle of the array cuz es6
162+
declarations[declarations.length - 1]?.id?.name || // work react application;
161163
(Array.isArray(declarations[0]?.id?.elements)
162164
? declarations[0]?.id?.elements[0]?.name
163165
: undefined); //work for nextJS & Remix
164166
// Push reactHook & varName to statements array
165167
/**
166-
* Mark's notes, it's interesting that they don't want to
167-
* pass on reactHook 'useState'. I wonder why.
168+
* Mark's notes, I'd like to alter the structure of the data
169+
* to pass on the reactHook 'useState'. That way the user will
170+
* eventually be able to view the difference between variables
171+
* stored via useState and useContext
168172
*/
169173
statements.push({ hookName, varName });
170174
}

src/extension/build/devtools.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<meta charset="UTF-8">
66
<meta name="viewport" content="width=device-width, initial-scale=1.0">
77
<meta http-equiv="X-UA-Compatible" content="ie=edge">
8-
<title>Reactime v9</title>
8+
<title>Reactime v19</title>
99
</head>
1010

1111
<body>

src/extension/build/panel.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<meta charset="UTF-8" />
55
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
66
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
7-
<title>Reactime 18.0</title>
7+
<title>Reactime 19.0</title>
88
</head>
99

1010
<body>

0 commit comments

Comments
 (0)