Skip to content

Commit c07c54a

Browse files
committedMar 18, 2021
Move ReactDevTools to its own module
1 parent 065d6ec commit c07c54a

File tree

4 files changed

+106
-109
lines changed

4 files changed

+106
-109
lines changed
 

‎src/ui/actions/app.ts

-6
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,6 @@ export function setupApp(recordingId: RecordingId, store: UIStore) {
9595
});
9696

9797
ThreadFront.listenForLoadChanges();
98-
99-
// ThreadFront.getAnnotations(({ annotations }) => {
100-
// for (const { point, time, kind, contents } of annotations) {
101-
// console.log("FoundAnnotation", point, time, kind, contents);
102-
// }
103-
// });
10498
}
10599

106100
function onUnprocessedRegions({ regions }: unprocessedRegions): UIThunkAction {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
import React from "react";
2+
3+
import {
4+
createBridge,
5+
createStore,
6+
initialize as createDevTools,
7+
} from "react-devtools-inline/frontend";
8+
import { ThreadFront } from "protocol/thread";
9+
import { features } from "ui/utils/prefs";
10+
11+
let bridge, store, wall, DevTools;
12+
let currentTime = null;
13+
let rerenderComponentsTab;
14+
const messages = [];
15+
16+
function InitReactDevTools() {
17+
if (!features.reactDevtools) {
18+
return null;
19+
}
20+
21+
const target = {
22+
postMessage: function () {},
23+
};
24+
25+
wall = {
26+
emit({ data }) {},
27+
listen(listener) {
28+
wall._listener = listener;
29+
},
30+
send(event, payload, transferable) {
31+
wall._listener({ event, payload });
32+
},
33+
};
34+
35+
bridge = createBridge(target, wall);
36+
store = createStore(bridge);
37+
DevTools = createDevTools(target, { bridge, store });
38+
}
39+
40+
InitReactDevTools();
41+
42+
ThreadFront.getAnnotations(({ annotations }) => {
43+
for (const { point, time, kind, contents } of annotations) {
44+
const message = JSON.parse(contents);
45+
messages.push({ point, time, message });
46+
}
47+
});
48+
49+
ThreadFront.on("paused", data => {
50+
if (currentTime === data.time) {
51+
return;
52+
}
53+
54+
InitReactDevTools();
55+
56+
// TODO Use point AND time eventually
57+
messages
58+
.filter(({ time }) => time <= data.time)
59+
.forEach(({ message }) => {
60+
if (message.event === "operations") {
61+
wall.send(message.event, message.payload);
62+
}
63+
});
64+
65+
// HACK TODO This should use a subscription
66+
if (typeof rerenderComponentsTab === "function") {
67+
rerenderComponentsTab();
68+
}
69+
});
70+
71+
// TODO Pass custom bridge
72+
// TODO Use portal containers for Profiler & Components
73+
export function ReactDevtoolsPanel() {
74+
if (!features.reactDevtools) {
75+
return null;
76+
}
77+
78+
const [count, setCount] = React.useState(0);
79+
80+
// HACK TODO This hack handles the fact that DevTools wasn't writen
81+
// with the expectation that a new Bridge or Store prop would be pasesd
82+
// and doens't handle that case properly.
83+
rerenderComponentsTab = () => {
84+
setCount(count + 1);
85+
};
86+
87+
React.useLayoutEffect(() => () => {
88+
rerenderComponentsTab = null;
89+
});
90+
91+
return (
92+
<DevTools
93+
bridge={bridge}
94+
browserTheme="light"
95+
enabledInspectedElementContextMenu={false}
96+
overrideTab="components"
97+
showTabBar={false}
98+
store={store}
99+
/>
100+
);
101+
}

‎src/ui/components/SecondaryToolbox/index.js

+4-101
Original file line numberDiff line numberDiff line change
@@ -6,77 +6,12 @@ import { features } from "ui/utils/prefs";
66
import Video from "../Video";
77
import WebConsoleApp from "devtools/client/webconsole/components/App";
88
import InspectorApp from "devtools/client/inspector/components/App";
9-
import {
10-
createBridge,
11-
createStore,
12-
initialize as createDevTools,
13-
} from "react-devtools-inline/frontend";
14-
import { ThreadFront } from "protocol/thread";
159

1610
import "./SecondaryToolbox.css";
1711
import NodePicker from "../NodePicker";
1812
import { selectors } from "../../reducers";
1913
import { actions } from "../../actions";
20-
21-
let bridge, store, wall, DevTools;
22-
23-
function InitReactDevTools() {
24-
if (!features.reactDevtools) {
25-
return null;
26-
}
27-
const target = {
28-
postMessage: function () {},
29-
};
30-
31-
wall = {
32-
emit({ data }) {},
33-
listen(listener) {
34-
wall._listener = listener;
35-
},
36-
send(event: string, payload: any, transferable?: Array<any>) {
37-
wall._listener({ event, payload });
38-
},
39-
};
40-
41-
bridge = createBridge(target, wall);
42-
store = createStore(bridge);
43-
DevTools = createDevTools(target, { bridge, store });
44-
}
45-
46-
InitReactDevTools();
47-
48-
const messages = [];
49-
ThreadFront.getAnnotations(({ annotations }) => {
50-
for (const { point, time, kind, contents } of annotations) {
51-
const message = JSON.parse(contents);
52-
messages.push({ point, time, message });
53-
}
54-
});
55-
56-
let currentTime = null;
57-
let rerenderComponentsTab = null;
58-
59-
ThreadFront.on("paused", data => {
60-
if (currentTime === data.time) {
61-
return;
62-
}
63-
64-
InitReactDevTools();
65-
66-
// TODO Use point AND time eventually
67-
messages
68-
.filter(({ time }) => time <= data.time)
69-
.forEach(({ message }) => {
70-
if (message.event === "operations") {
71-
wall.send(message.event, message.payload);
72-
}
73-
});
74-
75-
// HACK TODO This should use a subscription
76-
if (typeof rerenderComponentsTab === "function") {
77-
rerenderComponentsTab();
78-
}
79-
});
14+
import { ReactDevtoolsPanel } from "./ReactDevTools";
8015

8116
function PanelButtons({ selectedPanel, setSelectedPanel, narrowMode }) {
8217
const {
@@ -123,9 +58,9 @@ function PanelButtons({ selectedPanel, setSelectedPanel, narrowMode }) {
12358
{features.reactDevtools && (
12459
<button
12560
className={classnames("components-panel-button", {
126-
expanded: selectedPanel === "components",
61+
expanded: selectedPanel === "react-components",
12762
})}
128-
onClick={() => onClick("components")}
63+
onClick={() => onClick("react-components")}
12964
>
13065
<div className="label">⚛️ Components</div>
13166
</button>
@@ -152,38 +87,6 @@ function InspectorPanel() {
15287
);
15388
}
15489

155-
// TODO Pass custom bridge
156-
// TODO Use portal containers for Profiler & Components
157-
function Components() {
158-
if (!features.reactDevtools) {
159-
return null;
160-
}
161-
162-
const [count, setCount] = React.useState(0);
163-
164-
// HACK TODO This hack handles the fact that DevTools wasn't writen
165-
// with the expectation that a new Bridge or Store prop would be pasesd
166-
// and doens't handle that case properly.
167-
rerenderComponentsTab = () => {
168-
setCount(count + 1);
169-
};
170-
171-
React.useLayoutEffect(() => () => {
172-
rerenderComponentsTab = null;
173-
});
174-
175-
return (
176-
<DevTools
177-
bridge={bridge}
178-
browserTheme="light"
179-
enabledInspectedElementContextMenu={false}
180-
overrideTab="components"
181-
showTabBar={false}
182-
store={store}
183-
/>
184-
);
185-
}
186-
18790
function SecondaryToolbox({ selectedPanel, setSelectedPanel, narrowMode }) {
18891
const {
18992
userSettings: { show_elements },
@@ -202,7 +105,7 @@ function SecondaryToolbox({ selectedPanel, setSelectedPanel, narrowMode }) {
202105
{selectedPanel == "console" ? <ConsolePanel /> : null}
203106
{selectedPanel == "inspector" && show_elements ? <InspectorPanel /> : null}
204107
{selectedPanel == "viewer" && narrowMode ? <Video /> : null}
205-
{selectedPanel == "components" ? <Components /> : null}
108+
{selectedPanel == "react-components" ? <ReactDevtoolsPanel /> : null}
206109
</div>
207110
</div>
208111
);

‎src/ui/utils/devtools-toolbox.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,7 @@ export class DevToolsToolbox {
4545
}
4646

4747
startPanel = async name => {
48-
if (name === 'components') {
49-
// TODO
48+
if (name === "react-components") {
5049
return;
5150
}
5251

0 commit comments

Comments
 (0)