Automatically cause reload to trigger devTools
Summary: To connect to the React Devtools, the app has to be reload (or the dev menu opened). This diff does force a reload if the React Devtools don't connect timely Reviewed By: passy Differential Revision: D19878172 fbshipit-source-id: 0b3e22f70c9d24dae1fdbf0cc351d23367654ae1
This commit is contained in:
committed by
Facebook Github Bot
parent
3849807d6b
commit
56297d0cfc
@@ -65,15 +65,7 @@ const ProgressBarBar = styled.div<{progress: number; color: string}>(
|
|||||||
function MetroButton({device}: Props) {
|
function MetroButton({device}: Props) {
|
||||||
const sendCommand = useCallback(
|
const sendCommand = useCallback(
|
||||||
(command: string) => {
|
(command: string) => {
|
||||||
if (device.ws) {
|
device.sendCommand(command);
|
||||||
device.ws.send(
|
|
||||||
JSON.stringify({
|
|
||||||
version: 2,
|
|
||||||
type: 'command',
|
|
||||||
command,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
[device],
|
[device],
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ export default class MetroDevice extends BaseDevice {
|
|||||||
ws.onmessage = this._handleWSMessage;
|
ws.onmessage = this._handleWSMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
_handleWSMessage = ({data}: any) => {
|
private _handleWSMessage = ({data}: any) => {
|
||||||
const message: MetroReportableEvent = JSON.parse(data);
|
const message: MetroReportableEvent = JSON.parse(data);
|
||||||
if (message.type === 'client_log') {
|
if (message.type === 'client_log') {
|
||||||
const type: LogLevel = metroLogLevelMapping[message.level] || 'unknown';
|
const type: LogLevel = metroLogLevelMapping[message.level] || 'unknown';
|
||||||
@@ -182,6 +182,21 @@ export default class MetroDevice extends BaseDevice {
|
|||||||
this.metroEventEmitter.emit('event', message);
|
this.metroEventEmitter.emit('event', message);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
sendCommand(command: string, params?: any) {
|
||||||
|
if (this.ws) {
|
||||||
|
this.ws.send(
|
||||||
|
JSON.stringify({
|
||||||
|
version: 2,
|
||||||
|
type: 'command',
|
||||||
|
command,
|
||||||
|
params,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
console.warn('Cannot send command, no connection', command);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
archive() {
|
archive() {
|
||||||
return new ArchivedDevice(
|
return new ArchivedDevice(
|
||||||
this.serial + v4(),
|
this.serial + v4(),
|
||||||
|
|||||||
@@ -7,9 +7,19 @@
|
|||||||
* @format
|
* @format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// import {ReactReduxContext} from 'react-redux';
|
||||||
import ReactDevToolsStandalone from 'react-devtools-core/standalone';
|
import ReactDevToolsStandalone from 'react-devtools-core/standalone';
|
||||||
import {FlipperPlugin, AndroidDevice, styled, View, Toolbar} from 'flipper';
|
import {
|
||||||
import React from 'react';
|
FlipperPlugin,
|
||||||
|
AndroidDevice,
|
||||||
|
styled,
|
||||||
|
View,
|
||||||
|
Toolbar,
|
||||||
|
MetroDevice,
|
||||||
|
ReduxState,
|
||||||
|
connect,
|
||||||
|
} from 'flipper';
|
||||||
|
import React, {useEffect} from 'react';
|
||||||
import getPort from 'get-port';
|
import getPort from 'get-port';
|
||||||
import address from 'address';
|
import address from 'address';
|
||||||
|
|
||||||
@@ -54,7 +64,30 @@ function detachDevTools(devToolsNode: HTMLElement) {
|
|||||||
|
|
||||||
const CONNECTED = 'DevTools connected';
|
const CONNECTED = 'DevTools connected';
|
||||||
|
|
||||||
export default class extends FlipperPlugin<
|
type GrabMetroDeviceStoreProps = {metroDevice: MetroDevice};
|
||||||
|
type GrabMetroDeviceOwnProps = {onHasDevice(device: MetroDevice): void};
|
||||||
|
|
||||||
|
// Utility component to grab the metroDevice from the store if there is one
|
||||||
|
const GrabMetroDevice = connect<
|
||||||
|
GrabMetroDeviceStoreProps,
|
||||||
|
{},
|
||||||
|
GrabMetroDeviceOwnProps,
|
||||||
|
ReduxState
|
||||||
|
>(({connections: {devices}}) => ({
|
||||||
|
metroDevice: devices.find(
|
||||||
|
device => device.os === 'Metro' && !device.isArchived,
|
||||||
|
) as MetroDevice,
|
||||||
|
}))(function({
|
||||||
|
metroDevice,
|
||||||
|
onHasDevice,
|
||||||
|
}: GrabMetroDeviceStoreProps & GrabMetroDeviceOwnProps) {
|
||||||
|
useEffect(() => {
|
||||||
|
onHasDevice(metroDevice);
|
||||||
|
}, [metroDevice]);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
export default class ReactDevTools extends FlipperPlugin<
|
||||||
{
|
{
|
||||||
status: string;
|
status: string;
|
||||||
},
|
},
|
||||||
@@ -64,6 +97,7 @@ export default class extends FlipperPlugin<
|
|||||||
pollHandle?: NodeJS.Timeout;
|
pollHandle?: NodeJS.Timeout;
|
||||||
containerRef: React.RefObject<HTMLDivElement> = React.createRef();
|
containerRef: React.RefObject<HTMLDivElement> = React.createRef();
|
||||||
triedToAutoConnect = false;
|
triedToAutoConnect = false;
|
||||||
|
metroDevice?: MetroDevice;
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
status: 'initializing',
|
status: 'initializing',
|
||||||
@@ -98,7 +132,7 @@ export default class extends FlipperPlugin<
|
|||||||
}
|
}
|
||||||
|
|
||||||
setStatus(status: string) {
|
setStatus(status: string) {
|
||||||
console.log(`[ReactDevtoolsPlugin] ${status}`);
|
// console.log(`[ReactDevtoolsPlugin] ${status}`);
|
||||||
if (status.startsWith('The server is listening on')) {
|
if (status.startsWith('The server is listening on')) {
|
||||||
this.setState({status: status + ' Waiting for connection...'});
|
this.setState({status: status + ' Waiting for connection...'});
|
||||||
} else {
|
} else {
|
||||||
@@ -114,9 +148,14 @@ export default class extends FlipperPlugin<
|
|||||||
if (!this.triedToAutoConnect) {
|
if (!this.triedToAutoConnect) {
|
||||||
this.triedToAutoConnect = true;
|
this.triedToAutoConnect = true;
|
||||||
this.setStatus(
|
this.setStatus(
|
||||||
"The DevTools didn't connect yet. Please open the DevMenu or Reload to connect",
|
"The DevTools didn't connect yet. Please open the DevMenu in the React Native app, or Reload it to connect",
|
||||||
);
|
);
|
||||||
// TODO: send reload command
|
if (this.metroDevice) {
|
||||||
|
this.setStatus(
|
||||||
|
"Sending 'reload' to the Metro to force the DevTools to connect...",
|
||||||
|
);
|
||||||
|
this.metroDevice?.sendCommand('reload');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
this.startPollForConnection();
|
this.startPollForConnection();
|
||||||
}
|
}
|
||||||
@@ -124,6 +163,7 @@ export default class extends FlipperPlugin<
|
|||||||
}
|
}
|
||||||
|
|
||||||
async initializeDevTools(devToolsNode: HTMLElement) {
|
async initializeDevTools(devToolsNode: HTMLElement) {
|
||||||
|
try {
|
||||||
this.setStatus('Waiting for port 8097');
|
this.setStatus('Waiting for port 8097');
|
||||||
const port = await getPort({port: 8097}); // default port for dev tools
|
const port = await getPort({port: 8097}); // default port for dev tools
|
||||||
this.setStatus('Starting DevTools server on ' + port);
|
this.setStatus('Starting DevTools server on ' + port);
|
||||||
@@ -151,6 +191,10 @@ export default class extends FlipperPlugin<
|
|||||||
(device as AndroidDevice).reverse([port, port]);
|
(device as AndroidDevice).reverse([port, port]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
this.setStatus('Failed to initialize DevTools: ' + e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@@ -160,6 +204,11 @@ export default class extends FlipperPlugin<
|
|||||||
<Toolbar>{this.state.status}</Toolbar>
|
<Toolbar>{this.state.status}</Toolbar>
|
||||||
) : null}
|
) : null}
|
||||||
<Container ref={this.containerRef} />
|
<Container ref={this.containerRef} />
|
||||||
|
<GrabMetroDevice
|
||||||
|
onHasDevice={device => {
|
||||||
|
this.metroDevice = device;
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user