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
This commit is contained in:
committed by
Facebook GitHub Bot
parent
3ff955c42b
commit
6bcb5a435b
@@ -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 (
|
||||
<LeftSidebar>
|
||||
@@ -61,6 +63,7 @@ export function AppInspect() {
|
||||
activeDevice,
|
||||
client,
|
||||
isAppConnected,
|
||||
hasSelectableDevices,
|
||||
)}
|
||||
{isDeviceConnected && isAppConnected && <BookmarkSection />}
|
||||
{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(
|
||||
</Text>
|
||||
</Layout.Horizontal>
|
||||
)
|
||||
) : (
|
||||
) : hasSelectableDevices ? (
|
||||
<Layout.Horizontal gap center>
|
||||
<ExclamationCircleOutlined style={{color: theme.warningColor}} />
|
||||
<Text
|
||||
@@ -155,5 +159,5 @@ function renderStatusMessage(
|
||||
No application selected
|
||||
</Text>
|
||||
</Layout.Horizontal>
|
||||
);
|
||||
) : null /* no selectable devices */;
|
||||
}
|
||||
|
||||
@@ -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<string, Client>,
|
||||
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 = (
|
||||
<Menu.Item
|
||||
icon={getOsIcon(device.os)}
|
||||
key={device.serial}
|
||||
style={{fontWeight: 'bold'}}
|
||||
onClick={() => {
|
||||
onSelectDevice(device);
|
||||
}}>
|
||||
<DeviceTitle device={device} />
|
||||
</Menu.Item>
|
||||
);
|
||||
const clientEntries = getClientsByDevice(device, clients).map(
|
||||
(client) => (
|
||||
<Menu.Item
|
||||
key={client.id}
|
||||
onClick={() => {
|
||||
onSelectApp(device, client);
|
||||
}}>
|
||||
<Radio value={client.id}>
|
||||
<ClientTitle client={client} />
|
||||
</Radio>
|
||||
</Menu.Item>
|
||||
),
|
||||
);
|
||||
return [deviceEntry, ...clientEntries];
|
||||
});
|
||||
const entries = selectableDevices.map((device) => {
|
||||
const deviceEntry = (
|
||||
<Menu.Item
|
||||
icon={getOsIcon(device.os)}
|
||||
key={device.serial}
|
||||
style={{fontWeight: 'bold'}}
|
||||
onClick={() => {
|
||||
onSelectDevice(device);
|
||||
}}>
|
||||
<DeviceTitle device={device} />
|
||||
</Menu.Item>
|
||||
);
|
||||
const clientEntries = getClientsByDevice(device, clients).map((client) => (
|
||||
<Menu.Item
|
||||
key={client.id}
|
||||
onClick={() => {
|
||||
onSelectApp(device, client);
|
||||
}}>
|
||||
<Radio value={client.id}>
|
||||
<ClientTitle client={client} />
|
||||
</Radio>
|
||||
</Menu.Item>
|
||||
));
|
||||
return [deviceEntry, ...clientEntries];
|
||||
});
|
||||
if (uninitializedClients.length) {
|
||||
entries.push([
|
||||
<Menu.Item key="connecting" style={{fontWeight: 'bold'}}>
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user