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,
|
getActiveDevice,
|
||||||
getMetroDevice,
|
getMetroDevice,
|
||||||
} from '../../selectors/connections';
|
} from '../../selectors/connections';
|
||||||
|
import * as connections from '../../selectors/connections';
|
||||||
|
|
||||||
const {Text} = Typography;
|
const {Text} = Typography;
|
||||||
|
|
||||||
@@ -46,6 +47,7 @@ export function AppInspect() {
|
|||||||
const activeDevice = useSelector(getActiveDevice);
|
const activeDevice = useSelector(getActiveDevice);
|
||||||
const isDeviceConnected = useValue(activeDevice?.connected, false);
|
const isDeviceConnected = useValue(activeDevice?.connected, false);
|
||||||
const isAppConnected = useValue(client?.connected, false);
|
const isAppConnected = useValue(client?.connected, false);
|
||||||
|
const hasSelectableDevices = useSelector(connections.hasSelectableDevices);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<LeftSidebar>
|
<LeftSidebar>
|
||||||
@@ -61,6 +63,7 @@ export function AppInspect() {
|
|||||||
activeDevice,
|
activeDevice,
|
||||||
client,
|
client,
|
||||||
isAppConnected,
|
isAppConnected,
|
||||||
|
hasSelectableDevices,
|
||||||
)}
|
)}
|
||||||
{isDeviceConnected && isAppConnected && <BookmarkSection />}
|
{isDeviceConnected && isAppConnected && <BookmarkSection />}
|
||||||
{isDeviceConnected && activeDevice && (
|
{isDeviceConnected && activeDevice && (
|
||||||
@@ -96,6 +99,7 @@ function renderStatusMessage(
|
|||||||
activeDevice: BaseDevice | null,
|
activeDevice: BaseDevice | null,
|
||||||
client: Client | null,
|
client: Client | null,
|
||||||
isAppConnected: boolean,
|
isAppConnected: boolean,
|
||||||
|
hasSelectableDevices: boolean,
|
||||||
): React.ReactNode {
|
): React.ReactNode {
|
||||||
if (!activeDevice) {
|
if (!activeDevice) {
|
||||||
return;
|
return;
|
||||||
@@ -142,7 +146,7 @@ function renderStatusMessage(
|
|||||||
</Text>
|
</Text>
|
||||||
</Layout.Horizontal>
|
</Layout.Horizontal>
|
||||||
)
|
)
|
||||||
) : (
|
) : hasSelectableDevices ? (
|
||||||
<Layout.Horizontal gap center>
|
<Layout.Horizontal gap center>
|
||||||
<ExclamationCircleOutlined style={{color: theme.warningColor}} />
|
<ExclamationCircleOutlined style={{color: theme.warningColor}} />
|
||||||
<Text
|
<Text
|
||||||
@@ -155,5 +159,5 @@ function renderStatusMessage(
|
|||||||
No application selected
|
No application selected
|
||||||
</Text>
|
</Text>
|
||||||
</Layout.Horizontal>
|
</Layout.Horizontal>
|
||||||
);
|
) : null /* no selectable devices */;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,10 +18,9 @@ import {
|
|||||||
} from '@ant-design/icons';
|
} from '@ant-design/icons';
|
||||||
import {Glyph, Layout, styled} from '../../ui';
|
import {Glyph, Layout, styled} from '../../ui';
|
||||||
import {DeviceOS, theme, useTrackedCallback, useValue} from 'flipper-plugin';
|
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 {useDispatch, useStore} from '../../utils/useStore';
|
||||||
import {
|
import {
|
||||||
canBeDefaultDevice,
|
|
||||||
getClientsByDevice,
|
getClientsByDevice,
|
||||||
selectClient,
|
selectClient,
|
||||||
selectDevice,
|
selectDevice,
|
||||||
@@ -32,6 +31,7 @@ import {State} from '../../reducers';
|
|||||||
import {brandColors, brandIcons, colors} from '../../ui/components/colors';
|
import {brandColors, brandIcons, colors} from '../../ui/components/colors';
|
||||||
import {TroubleshootingGuide} from './fb-stubs/TroubleshootingGuide';
|
import {TroubleshootingGuide} from './fb-stubs/TroubleshootingGuide';
|
||||||
import GK from '../../fb-stubs/GK';
|
import GK from '../../fb-stubs/GK';
|
||||||
|
import {getSelectableDevices} from '../../selectors/connections';
|
||||||
|
|
||||||
const {Text} = Typography;
|
const {Text} = Typography;
|
||||||
|
|
||||||
@@ -50,13 +50,9 @@ function getOsIcon(os?: DeviceOS) {
|
|||||||
|
|
||||||
export function AppSelector() {
|
export function AppSelector() {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const {
|
const selectableDevices = useSelector(getSelectableDevices);
|
||||||
devices,
|
const {selectedDevice, clients, uninitializedClients, selectedAppId} =
|
||||||
selectedDevice,
|
useStore((state) => state.connections);
|
||||||
clients,
|
|
||||||
uninitializedClients,
|
|
||||||
selectedAppId,
|
|
||||||
} = useStore((state) => state.connections);
|
|
||||||
useValue(selectedDevice?.connected, false); // subscribe to future archived state changes
|
useValue(selectedDevice?.connected, false); // subscribe to future archived state changes
|
||||||
|
|
||||||
const onSelectDevice = useTrackedCallback(
|
const onSelectDevice = useTrackedCallback(
|
||||||
@@ -79,7 +75,7 @@ export function AppSelector() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const entries = computeEntries(
|
const entries = computeEntries(
|
||||||
devices,
|
selectableDevices,
|
||||||
clients,
|
clients,
|
||||||
uninitializedClients,
|
uninitializedClients,
|
||||||
onSelectDevice,
|
onSelectDevice,
|
||||||
@@ -193,47 +189,37 @@ const AppIconContainer = styled.div({
|
|||||||
});
|
});
|
||||||
|
|
||||||
function computeEntries(
|
function computeEntries(
|
||||||
devices: BaseDevice[],
|
selectableDevices: BaseDevice[],
|
||||||
clients: Map<string, Client>,
|
clients: Map<string, Client>,
|
||||||
uninitializedClients: State['connections']['uninitializedClients'],
|
uninitializedClients: State['connections']['uninitializedClients'],
|
||||||
onSelectDevice: (device: BaseDevice) => void,
|
onSelectDevice: (device: BaseDevice) => void,
|
||||||
onSelectApp: (device: BaseDevice, client: Client) => void,
|
onSelectApp: (device: BaseDevice, client: Client) => void,
|
||||||
) {
|
) {
|
||||||
const entries = devices
|
const entries = selectableDevices.map((device) => {
|
||||||
.filter(
|
const deviceEntry = (
|
||||||
(device) =>
|
<Menu.Item
|
||||||
// hide non default devices, unless they have a connected client or plugins
|
icon={getOsIcon(device.os)}
|
||||||
canBeDefaultDevice(device) ||
|
key={device.serial}
|
||||||
device.hasDevicePlugins ||
|
style={{fontWeight: 'bold'}}
|
||||||
getClientsByDevice(device, clients).length > 0,
|
onClick={() => {
|
||||||
)
|
onSelectDevice(device);
|
||||||
.map((device) => {
|
}}>
|
||||||
const deviceEntry = (
|
<DeviceTitle device={device} />
|
||||||
<Menu.Item
|
</Menu.Item>
|
||||||
icon={getOsIcon(device.os)}
|
);
|
||||||
key={device.serial}
|
const clientEntries = getClientsByDevice(device, clients).map((client) => (
|
||||||
style={{fontWeight: 'bold'}}
|
<Menu.Item
|
||||||
onClick={() => {
|
key={client.id}
|
||||||
onSelectDevice(device);
|
onClick={() => {
|
||||||
}}>
|
onSelectApp(device, client);
|
||||||
<DeviceTitle device={device} />
|
}}>
|
||||||
</Menu.Item>
|
<Radio value={client.id}>
|
||||||
);
|
<ClientTitle client={client} />
|
||||||
const clientEntries = getClientsByDevice(device, clients).map(
|
</Radio>
|
||||||
(client) => (
|
</Menu.Item>
|
||||||
<Menu.Item
|
));
|
||||||
key={client.id}
|
return [deviceEntry, ...clientEntries];
|
||||||
onClick={() => {
|
});
|
||||||
onSelectApp(device, client);
|
|
||||||
}}>
|
|
||||||
<Radio value={client.id}>
|
|
||||||
<ClientTitle client={client} />
|
|
||||||
</Radio>
|
|
||||||
</Menu.Item>
|
|
||||||
),
|
|
||||||
);
|
|
||||||
return [deviceEntry, ...clientEntries];
|
|
||||||
});
|
|
||||||
if (uninitializedClients.length) {
|
if (uninitializedClients.length) {
|
||||||
entries.push([
|
entries.push([
|
||||||
<Menu.Item key="connecting" style={{fontWeight: 'bold'}}>
|
<Menu.Item key="connecting" style={{fontWeight: 'bold'}}>
|
||||||
|
|||||||
@@ -14,10 +14,12 @@ import {
|
|||||||
computeActivePluginList,
|
computeActivePluginList,
|
||||||
} from '../utils/pluginUtils';
|
} from '../utils/pluginUtils';
|
||||||
import createSelector from './createSelector';
|
import createSelector from './createSelector';
|
||||||
|
import {canBeDefaultDevice, getClientsByDevice} from '../reducers/connections';
|
||||||
|
|
||||||
const getSelectedPluginId = (state: State) => state.connections.selectedPlugin;
|
const getSelectedPluginId = (state: State) => state.connections.selectedPlugin;
|
||||||
const getSelectedDevice = (state: State) => state.connections.selectedDevice;
|
const getSelectedDevice = (state: State) => state.connections.selectedDevice;
|
||||||
const getDevices = (state: State) => state.connections.devices;
|
const getDevices = (state: State) => state.connections.devices;
|
||||||
|
const getClients = (state: State) => state.connections.clients;
|
||||||
const getPluginDownloads = (state: State) => state.pluginDownloads;
|
const getPluginDownloads = (state: State) => state.pluginDownloads;
|
||||||
|
|
||||||
// N.B. no useSelector, It can't memoise on maps :-/
|
// 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(
|
export const getActiveDevice = createSelector(
|
||||||
getSelectedDevice,
|
getSelectedDevice,
|
||||||
getActiveClient,
|
getActiveClient,
|
||||||
|
|||||||
Reference in New Issue
Block a user