Summary: The path where a plugin was loaded from was not displayed correctly before, but pointed to Flipper's cache directory. Plugins that are bundled with Flippers application package are now marked as bundled. Dynamically loaded plugins show the path where they are loaded from. Reviewed By: passy Differential Revision: D13622148 fbshipit-source-id: 7951ecd37e45d2d4b3a55bd7dc126697367c7e69
348 lines
8.2 KiB
JavaScript
348 lines
8.2 KiB
JavaScript
/**
|
|
* Copyright 2018-present Facebook.
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
* @format
|
|
*/
|
|
|
|
import type {FlipperDevicePlugin, FlipperPlugin} from '../plugin';
|
|
import type {PluginDefinition} from '../dispatcher/plugins';
|
|
import type Client from '../Client';
|
|
|
|
import {Component, Fragment} from 'react';
|
|
import {connect} from 'react-redux';
|
|
import {
|
|
FlexColumn,
|
|
Button,
|
|
Text,
|
|
ManagedTable,
|
|
styled,
|
|
colors,
|
|
Link,
|
|
} from 'flipper';
|
|
import {remote} from 'electron';
|
|
|
|
const Container = styled(FlexColumn)({
|
|
padding: 10,
|
|
width: 700,
|
|
});
|
|
|
|
const InfoText = styled(Text)({
|
|
lineHeight: '130%',
|
|
marginBottom: 8,
|
|
});
|
|
|
|
const Title = styled('div')({
|
|
fontWeight: '500',
|
|
marginBottom: 10,
|
|
marginTop: 8,
|
|
});
|
|
|
|
const Ellipsis = styled(Text)({
|
|
overflow: 'hidden',
|
|
textOverflow: 'ellipsis',
|
|
whiteSpace: 'nowrap',
|
|
});
|
|
|
|
const Row = styled(FlexColumn)({
|
|
alignItems: 'flex-end',
|
|
});
|
|
|
|
const TableContainer = styled('div')({
|
|
borderRadius: 4,
|
|
overflow: 'hidden',
|
|
border: `1px solid ${colors.macOSTitleBarButtonBorder}`,
|
|
marginTop: 10,
|
|
marginBottom: 10,
|
|
backgroundColor: colors.white,
|
|
height: 400,
|
|
display: 'flex',
|
|
});
|
|
|
|
const Lamp = styled('div')(props => ({
|
|
width: 10,
|
|
height: 10,
|
|
borderRadius: 5,
|
|
backgroundColor: props.on ? colors.lime : colors.red,
|
|
border: `1px solid ${colors.blackAlpha30}`,
|
|
marginTop: 6,
|
|
flexShrink: 0,
|
|
}));
|
|
|
|
type Props = {|
|
|
devicePlugins: Array<FlipperDevicePlugin<>>,
|
|
clientPlugins: Array<FlipperPlugin<>>,
|
|
gatekeepedPlugins: Array<PluginDefinition>,
|
|
disabledPlugins: Array<PluginDefinition>,
|
|
failedPlugins: Array<[PluginDefinition, string]>,
|
|
clients: Array<Client>,
|
|
selectedDevice: ?string,
|
|
onHide: () => mixed,
|
|
|};
|
|
|
|
const COLUMNS = {
|
|
lamp: {
|
|
value: '',
|
|
},
|
|
name: {
|
|
value: 'Name',
|
|
},
|
|
status: {
|
|
value: 'Status',
|
|
},
|
|
gk: {
|
|
value: 'GK',
|
|
},
|
|
clients: {
|
|
value: 'Supported by',
|
|
},
|
|
source: {
|
|
value: 'Source',
|
|
},
|
|
};
|
|
|
|
const COLUMNS_SIZES = {
|
|
lamp: 20,
|
|
name: 'flex',
|
|
status: 110,
|
|
gk: 120,
|
|
clients: 90,
|
|
source: 140,
|
|
};
|
|
|
|
class PluginDebugger extends Component<Props> {
|
|
buildRow(
|
|
name: string,
|
|
loaded: boolean,
|
|
status: string,
|
|
GKname: ?string,
|
|
GKpassing: ?boolean,
|
|
pluginPath: ?string,
|
|
) {
|
|
return {
|
|
key: name.toLowerCase(),
|
|
columns: {
|
|
lamp: {value: <Lamp on={loaded} />},
|
|
name: {value: <Ellipsis>{name}</Ellipsis>},
|
|
status: {
|
|
value: status ? (
|
|
<Ellipsis title={status} passing={false}>
|
|
{status}
|
|
</Ellipsis>
|
|
) : null,
|
|
},
|
|
gk: {
|
|
value: GKname && (
|
|
<Ellipsis code title={GKname}>
|
|
{GKname}
|
|
</Ellipsis>
|
|
),
|
|
},
|
|
clients: {
|
|
value: this.getSupportedClients(name),
|
|
},
|
|
source: {
|
|
value: pluginPath ? (
|
|
<Ellipsis code title={pluginPath}>
|
|
{pluginPath}
|
|
</Ellipsis>
|
|
) : (
|
|
<i>bundled</i>
|
|
),
|
|
},
|
|
},
|
|
};
|
|
}
|
|
|
|
getSupportedClients(id: string): string {
|
|
return this.props.clients
|
|
.reduce((acc: Array<string>, cv: Client) => {
|
|
if (cv.plugins.includes(id)) {
|
|
acc.push(cv.query.app);
|
|
}
|
|
return acc;
|
|
}, [])
|
|
.join(', ');
|
|
}
|
|
|
|
getRows() {
|
|
let rows = [];
|
|
|
|
// bundled plugins are loaded from the defaultPlugins directory within
|
|
// Flipper's package.
|
|
const externalPluginPath = (p: PluginDefinition) =>
|
|
p.out.startsWith('./defaultPlugins/') ? null : p.entry;
|
|
|
|
this.props.gatekeepedPlugins.forEach(plugin =>
|
|
rows.push(
|
|
this.buildRow(
|
|
plugin.name,
|
|
false,
|
|
'GK disabled',
|
|
plugin.gatekeeper,
|
|
false,
|
|
externalPluginPath(plugin),
|
|
),
|
|
),
|
|
);
|
|
|
|
this.props.devicePlugins.forEach(plugin =>
|
|
rows.push(
|
|
this.buildRow(
|
|
plugin.id,
|
|
true,
|
|
'',
|
|
// $FlowFixMe: Flow doesn't know this is inherited from FlipperBasePlugin
|
|
plugin.gatekeeper,
|
|
true,
|
|
// $FlowFixMe: Flow doesn't know this is inherited from FlipperBasePlugin
|
|
externalPluginPath(plugin),
|
|
),
|
|
),
|
|
);
|
|
|
|
this.props.clientPlugins.forEach(plugin =>
|
|
rows.push(
|
|
this.buildRow(
|
|
plugin.id,
|
|
true,
|
|
'',
|
|
// $FlowFixMe: Flow doesn't know this is inherited from FlipperBasePlugin
|
|
plugin.gatekeeper,
|
|
true,
|
|
// $FlowFixMe: Flow doesn't know this is inherited from FlipperBasePlugin
|
|
externalPluginPath(plugin),
|
|
),
|
|
),
|
|
);
|
|
|
|
this.props.disabledPlugins.forEach(plugin =>
|
|
rows.push(
|
|
this.buildRow(
|
|
plugin.name,
|
|
false,
|
|
'disabled',
|
|
null,
|
|
null,
|
|
externalPluginPath(plugin),
|
|
),
|
|
),
|
|
);
|
|
|
|
this.props.failedPlugins.forEach(([plugin, status]) =>
|
|
rows.push(
|
|
this.buildRow(
|
|
plugin.name,
|
|
false,
|
|
status,
|
|
null,
|
|
null,
|
|
externalPluginPath(plugin),
|
|
),
|
|
),
|
|
);
|
|
|
|
return rows.sort((a, b) => (a.key < b.key ? -1 : 1));
|
|
}
|
|
|
|
render() {
|
|
let content = null;
|
|
|
|
if (!this.props.selectedDevice) {
|
|
content = (
|
|
<InfoText>
|
|
We can't find any device connected to your computer. Is an
|
|
emulator/simulator currently running on your system, or is there a
|
|
development device connected via USB? There are some devices/emulators
|
|
known to have problems connecting to Flipper. Check out the{' '}
|
|
<Link href="https://fbflipper.com/docs/troubleshooting.html#known-incompatibilities">
|
|
known incompatibilities
|
|
</Link>.
|
|
</InfoText>
|
|
);
|
|
} else if (
|
|
!this.props.clients.some(
|
|
(client: Client) =>
|
|
client.query.device_id === this.props.selectedDevice,
|
|
)
|
|
) {
|
|
// no clients for selected device
|
|
content = (
|
|
<Fragment>
|
|
<InfoText>
|
|
While Flipper was able to connect to your device, it wasn't able to
|
|
connect to the app you are running on your device. For this reason,
|
|
app-specific plugins will not show up.
|
|
</InfoText>
|
|
{this.props.clients.length > 0 && (
|
|
// we have clients, but not for this device
|
|
<InfoText>
|
|
Make sure you selected the correct device from the dropdown button
|
|
in the upper left corner. Only plugins for the selected device are
|
|
shown in the sidebar.
|
|
</InfoText>
|
|
)}
|
|
<InfoText>
|
|
To debug why Flipper couldn't establish a connection to the app,
|
|
check out our documentation about{' '}
|
|
<Link href="https://fbflipper.com/docs/troubleshooting.html#connection-issues">
|
|
connection issues
|
|
</Link>.
|
|
</InfoText>
|
|
</Fragment>
|
|
);
|
|
} else {
|
|
content = (
|
|
<Fragment>
|
|
<InfoText>
|
|
The table lists all plugins known to Flipper. Some of them might be
|
|
blocked by GKs, others may not show up, because none of the
|
|
connected apps is supporting it.
|
|
</InfoText>
|
|
<TableContainer>
|
|
<ManagedTable
|
|
columns={COLUMNS}
|
|
rows={this.getRows()}
|
|
highlightableRows={false}
|
|
columnSizes={COLUMNS_SIZES}
|
|
/>
|
|
</TableContainer>
|
|
</Fragment>
|
|
);
|
|
}
|
|
return (
|
|
<Container>
|
|
<Title>Plugin Status</Title>
|
|
{content}
|
|
<Row>
|
|
<Button compact padded onClick={this.props.onHide}>
|
|
Close
|
|
</Button>
|
|
</Row>
|
|
</Container>
|
|
);
|
|
}
|
|
}
|
|
|
|
// $FlowFixMe
|
|
export default connect(
|
|
({
|
|
plugins: {
|
|
devicePlugins,
|
|
clientPlugins,
|
|
gatekeepedPlugins,
|
|
disabledPlugins,
|
|
failedPlugins,
|
|
},
|
|
connections: {selectedPlugin, clients, selectedDevice},
|
|
}) => ({
|
|
devicePlugins: Array.from(devicePlugins.values()),
|
|
clientPlugins: Array.from(clientPlugins.values()),
|
|
gatekeepedPlugins,
|
|
clients,
|
|
disabledPlugins,
|
|
failedPlugins,
|
|
selectedDevice: selectedDevice?.serial,
|
|
}),
|
|
)(PluginDebugger);
|