From 6bcb5a435bff666fb7f8cbad0dc98cf736cb804e Mon Sep 17 00:00:00 2001 From: Gerard Delmas Date: Thu, 4 Nov 2021 05:12:35 -0700 Subject: [PATCH] Hide "no application selected" warning when there is no device Summary: In the left App Inspect sidebar on Flipper there were two warning messages - "no devices found" - "no application selected" As there can be no application selected, while no device is active, this change removes the "no application selected" warning. Resulting in only showing one warning at a time. As I am not familiar with all the states, nor what kind of devices or applications can exist in detail, I have moved up the logic to show the "no device found" message. Then reused it for the "no application selected" visibility. In case the upper device list can show "connecting" without an actual device in the list, the "no application selected" message will be shown. Reviewed By: passy Differential Revision: D32139077 fbshipit-source-id: 06456e81fbe1f86d65f9aba598ee84ed8cd6b043 --- .../sandy-chrome/appinspect/AppInspect.tsx | 8 +- .../sandy-chrome/appinspect/AppSelector.tsx | 78 ++++++++----------- desktop/app/src/selectors/connections.tsx | 21 +++++ 3 files changed, 59 insertions(+), 48 deletions(-) diff --git a/desktop/app/src/sandy-chrome/appinspect/AppInspect.tsx b/desktop/app/src/sandy-chrome/appinspect/AppInspect.tsx index bed93e91b..acd76291b 100644 --- a/desktop/app/src/sandy-chrome/appinspect/AppInspect.tsx +++ b/desktop/app/src/sandy-chrome/appinspect/AppInspect.tsx @@ -26,6 +26,7 @@ import { getActiveDevice, getMetroDevice, } from '../../selectors/connections'; +import * as connections from '../../selectors/connections'; const {Text} = Typography; @@ -46,6 +47,7 @@ export function AppInspect() { const activeDevice = useSelector(getActiveDevice); const isDeviceConnected = useValue(activeDevice?.connected, false); const isAppConnected = useValue(client?.connected, false); + const hasSelectableDevices = useSelector(connections.hasSelectableDevices); return ( @@ -61,6 +63,7 @@ export function AppInspect() { activeDevice, client, isAppConnected, + hasSelectableDevices, )} {isDeviceConnected && isAppConnected && } {isDeviceConnected && activeDevice && ( @@ -96,6 +99,7 @@ function renderStatusMessage( activeDevice: BaseDevice | null, client: Client | null, isAppConnected: boolean, + hasSelectableDevices: boolean, ): React.ReactNode { if (!activeDevice) { return; @@ -142,7 +146,7 @@ function renderStatusMessage( ) - ) : ( + ) : hasSelectableDevices ? ( - ); + ) : null /* no selectable devices */; } diff --git a/desktop/app/src/sandy-chrome/appinspect/AppSelector.tsx b/desktop/app/src/sandy-chrome/appinspect/AppSelector.tsx index 782d3e72d..5bfbb76cf 100644 --- a/desktop/app/src/sandy-chrome/appinspect/AppSelector.tsx +++ b/desktop/app/src/sandy-chrome/appinspect/AppSelector.tsx @@ -18,10 +18,9 @@ import { } from '@ant-design/icons'; import {Glyph, Layout, styled} from '../../ui'; import {DeviceOS, theme, useTrackedCallback, useValue} from 'flipper-plugin'; -import {batch} from 'react-redux'; +import {batch, useSelector} from 'react-redux'; import {useDispatch, useStore} from '../../utils/useStore'; import { - canBeDefaultDevice, getClientsByDevice, selectClient, selectDevice, @@ -32,6 +31,7 @@ import {State} from '../../reducers'; import {brandColors, brandIcons, colors} from '../../ui/components/colors'; import {TroubleshootingGuide} from './fb-stubs/TroubleshootingGuide'; import GK from '../../fb-stubs/GK'; +import {getSelectableDevices} from '../../selectors/connections'; const {Text} = Typography; @@ -50,13 +50,9 @@ function getOsIcon(os?: DeviceOS) { export function AppSelector() { const dispatch = useDispatch(); - const { - devices, - selectedDevice, - clients, - uninitializedClients, - selectedAppId, - } = useStore((state) => state.connections); + const selectableDevices = useSelector(getSelectableDevices); + const {selectedDevice, clients, uninitializedClients, selectedAppId} = + useStore((state) => state.connections); useValue(selectedDevice?.connected, false); // subscribe to future archived state changes const onSelectDevice = useTrackedCallback( @@ -79,7 +75,7 @@ export function AppSelector() { ); const entries = computeEntries( - devices, + selectableDevices, clients, uninitializedClients, onSelectDevice, @@ -193,47 +189,37 @@ const AppIconContainer = styled.div({ }); function computeEntries( - devices: BaseDevice[], + selectableDevices: BaseDevice[], clients: Map, uninitializedClients: State['connections']['uninitializedClients'], onSelectDevice: (device: BaseDevice) => void, onSelectApp: (device: BaseDevice, client: Client) => void, ) { - const entries = devices - .filter( - (device) => - // hide non default devices, unless they have a connected client or plugins - canBeDefaultDevice(device) || - device.hasDevicePlugins || - getClientsByDevice(device, clients).length > 0, - ) - .map((device) => { - const deviceEntry = ( - { - onSelectDevice(device); - }}> - - - ); - const clientEntries = getClientsByDevice(device, clients).map( - (client) => ( - { - onSelectApp(device, client); - }}> - - - - - ), - ); - return [deviceEntry, ...clientEntries]; - }); + const entries = selectableDevices.map((device) => { + const deviceEntry = ( + { + onSelectDevice(device); + }}> + + + ); + const clientEntries = getClientsByDevice(device, clients).map((client) => ( + { + onSelectApp(device, client); + }}> + + + + + )); + return [deviceEntry, ...clientEntries]; + }); if (uninitializedClients.length) { entries.push([ diff --git a/desktop/app/src/selectors/connections.tsx b/desktop/app/src/selectors/connections.tsx index 70b0048c0..9cbb2bfcb 100644 --- a/desktop/app/src/selectors/connections.tsx +++ b/desktop/app/src/selectors/connections.tsx @@ -14,10 +14,12 @@ import { computeActivePluginList, } from '../utils/pluginUtils'; import createSelector from './createSelector'; +import {canBeDefaultDevice, getClientsByDevice} from '../reducers/connections'; const getSelectedPluginId = (state: State) => state.connections.selectedPlugin; const getSelectedDevice = (state: State) => state.connections.selectedDevice; const getDevices = (state: State) => state.connections.devices; +const getClients = (state: State) => state.connections.clients; const getPluginDownloads = (state: State) => state.pluginDownloads; // N.B. no useSelector, It can't memoise on maps :-/ @@ -31,6 +33,25 @@ export const getMetroDevice = createSelector(getDevices, (devices) => { ); }); +export const getSelectableDevices = createSelector( + getDevices, + getClients, + (devices, clients) => { + return devices.filter( + (device) => + // hide non default devices, unless they have a connected client or plugins + canBeDefaultDevice(device) || + device.hasDevicePlugins || + getClientsByDevice(device, clients).length > 0, + ); + }, +); + +export const hasSelectableDevices = createSelector( + getSelectableDevices, + (selectableDevices) => selectableDevices.length > 0, +); + export const getActiveDevice = createSelector( getSelectedDevice, getActiveClient,