Be able to select Metro plugins

Summary:
This adds the ability in AppInspect to work with Metro and plugins.

Metro remains a weird and hardcoded edge case, as we show it as part of another device. So a few things to notice:
- Metro does not have it's own entry in the device/app dropdown
- When selecting a metro plugin, the surrounding context (selected main device / app) remains, but you will notice that the device dropdown switches to 'React Native'. This is intentional to reflect that we are talking to React Native in general, and not necessarily to the device / app shown in the context.

Reviewed By: nikoant

Differential Revision: D24422267

fbshipit-source-id: 239aa71b5c01e19bdda53a930ad9fa8af13b8d4a
This commit is contained in:
Michel Weststrate
2020-10-22 09:37:26 -07:00
committed by Facebook GitHub Bot
parent 8a7323b9f8
commit c55be74426
2 changed files with 63 additions and 13 deletions

View File

@@ -28,6 +28,7 @@ import {deconstructClientId} from '../utils/clientUtils';
import {PluginDefinition} from '../plugin';
import {RegisterPluginAction} from './plugins';
import {ConsoleLogs} from '../chrome/ConsoleLogs';
import MetroDevice from '../devices/MetroDevice';
export type StaticView =
| null
@@ -133,7 +134,7 @@ export type Action =
};
const DEFAULT_PLUGIN = 'DeviceLogs';
const DEFAULT_DEVICE_BLACKLIST = [MacDevice];
const DEFAULT_DEVICE_BLACKLIST = [MacDevice, MetroDevice];
const INITAL_STATE: State = {
devices: [],
androidEmulators: [],
@@ -268,7 +269,8 @@ export default (state: State = INITAL_STATE, action: Actions): State => {
selectedPlugin,
userPreferredPlugin: selectedPlugin || state.userPreferredPlugin,
selectedDevice: selectedDevice!,
userPreferredDevice: selectedDevice
userPreferredDevice:
selectedDevice && canBeDefaultDevice(selectedDevice)
? selectedDevice.title
: state.userPreferredDevice,
deepLinkPayload: deepLinkPayload,

View File

@@ -46,10 +46,47 @@ export const PluginList = memo(function PluginList() {
[connections.devices],
);
const client = useMemo(
() => connections.clients.find((c) => c.id === connections.selectedApp),
[connections.clients, connections.selectedApp],
() =>
connections.clients.find(
(c) =>
c.id === connections.selectedApp ||
c.id === connections.userPreferredApp,
),
[
connections.clients,
connections.selectedApp,
connections.userPreferredApp,
],
);
// // if the selected device is Metro, we want to keep the owner of the selected App as active device if possible
const activeDevice = useMemo<BaseDevice | undefined | null>(() => {
// if not Metro device, use the selected device as metro device
const selected = connections.selectedDevice;
if (selected !== metroDevice) {
return selected;
}
// if there is an active app, use device owning the app
if (client && client._deviceResolved) {
return client._deviceResolved;
}
// if no active app, use the preferred device
if (connections.userPreferredDevice) {
return (
connections.devices.find(
(device) => device.title === connections.userPreferredDevice,
) ?? selected
);
}
return selected;
}, [
client,
connections.devices,
connections.selectedDevice,
metroDevice,
connections.userPreferredDevice,
]);
const {
devicePlugins,
metroPlugins,
@@ -59,14 +96,14 @@ export const PluginList = memo(function PluginList() {
} = useMemo(
() =>
computePluginLists(
connections.selectedDevice!,
activeDevice!,
metroDevice,
client,
plugins,
connections.userStarredPlugins,
),
[
connections.selectedDevice,
activeDevice,
metroDevice,
plugins,
client,
@@ -81,11 +118,11 @@ export const PluginList = memo(function PluginList() {
selectedPlugin: pluginId,
selectedApp: connections.selectedApp,
deepLinkPayload: null,
selectedDevice: connections.selectedDevice,
selectedDevice: activeDevice,
}),
);
},
[dispatch, connections.selectedDevice, connections.selectedApp],
[dispatch, activeDevice, connections.selectedApp],
);
const handleMetroPluginClick = useCallback(
@@ -128,7 +165,10 @@ export const PluginList = memo(function PluginList() {
<PluginEntry
key={plugin.id}
plugin={plugin.details}
active={plugin.id === connections.selectedPlugin}
active={
plugin.id === connections.selectedPlugin &&
connections.selectedDevice === activeDevice
}
onClick={handleAppPluginClick}
tooltip={getPluginTooltip(plugin.details)}
/>
@@ -138,9 +178,12 @@ export const PluginList = memo(function PluginList() {
<PluginGroup key="metro" title="React Native">
{metroPlugins.map((plugin) => (
<PluginEntry
key={plugin.id}
key={'metro' + plugin.id}
plugin={plugin.details}
active={plugin.id === connections.selectedPlugin}
active={
plugin.id === connections.selectedPlugin &&
connections.selectedDevice === metroDevice
}
onClick={handleMetroPluginClick}
tooltip={getPluginTooltip(plugin.details)}
/>
@@ -159,6 +202,7 @@ export const PluginList = memo(function PluginList() {
<ActionButton
id={plugin.id}
onClick={handleStarPlugin}
title="Disable plugin"
icon={<MinusOutlined size={16} style={{marginRight: 0}} />}
/>
}
@@ -175,6 +219,7 @@ export const PluginList = memo(function PluginList() {
actions={
<ActionButton
id={plugin.id}
title="Enable plugin"
onClick={handleStarPlugin}
icon={<PlusOutlined size={16} style={{marginRight: 0}} />}
/>
@@ -212,8 +257,10 @@ function ActionButton({
icon,
onClick,
id,
title,
}: {
id: string;
title: string;
icon: React.ReactElement;
onClick: (id: string) => void;
}) {
@@ -221,6 +268,7 @@ function ActionButton({
<Button
size="small"
icon={icon}
title={title}
style={{border: 'none', color: theme.textColorPrimary}}
onClick={() => {
onClick(id);