Skip to content

Commit

Permalink
Move ReactDevTools to its own module
Browse files Browse the repository at this point in the history
  • Loading branch information
jasonLaster committed Mar 18, 2021
1 parent f531a92 commit eaaa2cc
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 105 deletions.
6 changes: 0 additions & 6 deletions src/ui/actions/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,6 @@ export function setupApp(recordingId: RecordingId, store: UIStore) {
});

ThreadFront.listenForLoadChanges();

// ThreadFront.getAnnotations(({ annotations }) => {
// for (const { point, time, kind, contents } of annotations) {
// console.log("FoundAnnotation", point, time, kind, contents);
// }
// });
}

function onUnprocessedRegions({ regions }: unprocessedRegions): UIThunkAction {
Expand Down
97 changes: 97 additions & 0 deletions src/ui/components/SecondaryToolbox/ReactDevTools.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import React from "react";

import {
createBridge,
createStore,
initialize as createDevTools,
} from "react-devtools-inline/frontend";
import { ThreadFront } from "protocol/thread";
import { features } from "ui/utils/prefs";

let bridge, store, wall, DevTools;
const messages = [];

function InitReactDevTools() {
if (!features.reactDevtools) {
return null;
}
const target = {
postMessage: function () {},
};

wall = {
emit() {},
listen(listener) {
wall._listener = listener;
},
send(event, payload) {
wall._listener({ event, payload });
},
};

bridge = createBridge(target, wall);
store = createStore(bridge);
DevTools = createDevTools(target, { bridge, store });
}

InitReactDevTools();

ThreadFront.getAnnotations(({ annotations }) => {
for (const { point, time, kind, contents } of annotations) {
const message = JSON.parse(contents);
messages.push({ point, time, message });
}
});

let currentTime = null;
let rerenderComponentsTab;

ThreadFront.on("paused", data => {
if (currentTime === data.time) {
return;
}

InitReactDevTools();

// TODO Use point AND time eventually
messages
.filter(({ time }) => time <= data.time)
.forEach(({ message }) => {
if (message.event === "operations") {
wall.send(message.event, message.payload);
}
});

// HACK TODO This should use a subscription
if (typeof rerenderComponentsTab === "function") {
rerenderComponentsTab();
}
});

// TODO Pass custom bridge
// TODO Use portal containers for Profiler & Components
export function ReactDevtoolsPanel() {
if (!features.reactDevtools) {
return null;
}

const [count, setCount] = React.useState(0);

// HACK TODO This hack handles the fact that DevTools wasn't writen
// with the expectation that a new Bridge or Store prop would be pasesd
// and doens't handle that case properly.
rerenderComponentsTab = () => {
setCount(count + 1);
};

return (
<DevTools
bridge={bridge}
browserTheme="light"
enabledInspectedElementContextMenu={false}
overrideTab="components"
showTabBar={false}
store={store}
/>
);
}
101 changes: 4 additions & 97 deletions src/ui/components/SecondaryToolbox/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,77 +6,12 @@ import { features } from "ui/utils/prefs";
import Video from "../Video";
import WebConsoleApp from "devtools/client/webconsole/components/App";
import InspectorApp from "devtools/client/inspector/components/App";
import {
createBridge,
createStore,
initialize as createDevTools,
} from "react-devtools-inline/frontend";
import { ThreadFront } from "protocol/thread";

import "./SecondaryToolbox.css";
import NodePicker from "../NodePicker";
import { selectors } from "../../reducers";
import { actions } from "../../actions";

let bridge, store, wall, DevTools;

function InitReactDevTools() {
if (!features.reactDevtools) {
return null;
}
const target = {
postMessage: function () {},
};

wall = {
emit({ data }) {},
listen(listener) {
wall._listener = listener;
},
send(event: string, payload: any, transferable?: Array<any>) {
wall._listener({ event, payload });
},
};

bridge = createBridge(target, wall);
store = createStore(bridge);
DevTools = createDevTools(target, { bridge, store });
}

InitReactDevTools();

const messages = [];
ThreadFront.getAnnotations(({ annotations }) => {
for (const { point, time, kind, contents } of annotations) {
const message = JSON.parse(contents);
messages.push({ point, time, message });
}
});

let currentTime = null;
let rerenderComponentsTab;

ThreadFront.on("paused", data => {
if (currentTime === data.time) {
return;
}

InitReactDevTools();

// TODO Use point AND time eventually
messages
.filter(({ time }) => time <= data.time)
.forEach(({ message }) => {
if (message.event === "operations") {
wall.send(message.event, message.payload);
}
});

// HACK TODO This should use a subscription
if (typeof rerenderComponentsTab === "function") {
rerenderComponentsTab();
}
});
import { ReactDevtoolsPanel } from "./ReactDevTools";

function PanelButtons({ selectedPanel, setSelectedPanel, narrowMode }) {
const {
Expand Down Expand Up @@ -123,9 +58,9 @@ function PanelButtons({ selectedPanel, setSelectedPanel, narrowMode }) {
{features.reactDevtools && (
<button
className={classnames("components-panel-button", {
expanded: selectedPanel === "components",
expanded: selectedPanel === "react-components",
})}
onClick={() => onClick("components")}
onClick={() => onClick("react-components")}
>
<div className="label">⚛️ Components</div>
</button>
Expand All @@ -152,34 +87,6 @@ function InspectorPanel() {
);
}

// TODO Pass custom bridge
// TODO Use portal containers for Profiler & Components
function Components() {
if (!features.reactDevtools) {
return null;
}

const [count, setCount] = React.useState(0);

// HACK TODO This hack handles the fact that DevTools wasn't writen
// with the expectation that a new Bridge or Store prop would be pasesd
// and doens't handle that case properly.
rerenderComponentsTab = () => {
setCount(count + 1);
};

return (
<DevTools
bridge={bridge}
browserTheme="light"
enabledInspectedElementContextMenu={false}
overrideTab="components"
showTabBar={false}
store={store}
/>
);
}

function SecondaryToolbox({ selectedPanel, setSelectedPanel, narrowMode }) {
const {
userSettings: { show_elements },
Expand All @@ -198,7 +105,7 @@ function SecondaryToolbox({ selectedPanel, setSelectedPanel, narrowMode }) {
{selectedPanel == "console" ? <ConsolePanel /> : null}
{selectedPanel == "inspector" && show_elements ? <InspectorPanel /> : null}
{selectedPanel == "viewer" && narrowMode ? <Video /> : null}
{selectedPanel == "components" ? <Components /> : null}
{selectedPanel == "react-components" ? <ReactDevtoolsPanel /> : null}
</div>
</div>
);
Expand Down
3 changes: 1 addition & 2 deletions src/ui/utils/devtools-toolbox.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,7 @@ export class DevToolsToolbox {
}

startPanel = async name => {
if (name === 'components') {
// TODO
if (name === "react-components") {
return;
}

Expand Down

0 comments on commit eaaa2cc

Please sign in to comment.