From c55be744263a6ef6bd58687f571a82f6f9a46e47 Mon Sep 17 00:00:00 2001 From: Michel Weststrate Date: Thu, 22 Oct 2020 09:37:26 -0700 Subject: [PATCH] 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 --- desktop/app/src/reducers/connections.tsx | 10 +-- .../sandy-chrome/appinspect/PluginList.tsx | 66 ++++++++++++++++--- 2 files changed, 63 insertions(+), 13 deletions(-) diff --git a/desktop/app/src/reducers/connections.tsx b/desktop/app/src/reducers/connections.tsx index 65440f05d..2f79a17e7 100644 --- a/desktop/app/src/reducers/connections.tsx +++ b/desktop/app/src/reducers/connections.tsx @@ -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,9 +269,10 @@ export default (state: State = INITAL_STATE, action: Actions): State => { selectedPlugin, userPreferredPlugin: selectedPlugin || state.userPreferredPlugin, selectedDevice: selectedDevice!, - userPreferredDevice: selectedDevice - ? selectedDevice.title - : state.userPreferredDevice, + userPreferredDevice: + selectedDevice && canBeDefaultDevice(selectedDevice) + ? selectedDevice.title + : state.userPreferredDevice, deepLinkPayload: deepLinkPayload, }); } diff --git a/desktop/app/src/sandy-chrome/appinspect/PluginList.tsx b/desktop/app/src/sandy-chrome/appinspect/PluginList.tsx index e78bc7f11..b1965851e 100644 --- a/desktop/app/src/sandy-chrome/appinspect/PluginList.tsx +++ b/desktop/app/src/sandy-chrome/appinspect/PluginList.tsx @@ -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(() => { + // 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() { @@ -138,9 +178,12 @@ export const PluginList = memo(function PluginList() { {metroPlugins.map((plugin) => ( @@ -159,6 +202,7 @@ export const PluginList = memo(function PluginList() { } /> } @@ -175,6 +219,7 @@ export const PluginList = memo(function PluginList() { actions={ } /> @@ -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({