Hide app selector if no devices are available
Summary: As reported in https://fb.workplace.com/groups/748354712423318/permalink/773382183253904/, special case no devices being present and suggest to launch an emulator. Also extends `useStore()` hook to accept no arguments, in which case it works as Redux's own `useStore` hook, except that it is strongly typed. Reviewed By: passy Differential Revision: D25803497 fbshipit-source-id: d448ac41e0ba7b713ee883caeb27736a2901975c
This commit is contained in:
committed by
Facebook GitHub Bot
parent
dbf194b952
commit
30ea098a63
@@ -47,7 +47,6 @@ import {logout, USER_NOT_SIGNEDIN, USER_UNAUTHORIZED} from '../reducers/user';
|
||||
import config from '../fb-stubs/config';
|
||||
import styled from '@emotion/styled';
|
||||
import {showEmulatorLauncher} from './appinspect/LaunchEmulator';
|
||||
import {useStore as useReduxStore} from 'react-redux';
|
||||
import SupportRequestFormV2 from '../fb-stubs/SupportRequestFormV2';
|
||||
import {setStaticView} from '../reducers/connections';
|
||||
import {getInstance} from '../fb-stubs/Logger';
|
||||
@@ -252,7 +251,7 @@ function DebugLogsButton({
|
||||
}
|
||||
|
||||
function LaunchEmulatorButton() {
|
||||
const store = useReduxStore();
|
||||
const store = useStore();
|
||||
|
||||
return (
|
||||
<LeftRailButton
|
||||
|
||||
@@ -8,12 +8,13 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import {Button, Dropdown, Menu, Radio, Typography} from 'antd';
|
||||
import {Alert, Button, Dropdown, Menu, Radio, Typography} from 'antd';
|
||||
import {
|
||||
AppleOutlined,
|
||||
AndroidOutlined,
|
||||
WindowsOutlined,
|
||||
CaretDownOutlined,
|
||||
RocketOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import {Glyph, Layout, styled} from '../../ui';
|
||||
import {theme, useTrackedCallback} from 'flipper-plugin';
|
||||
@@ -30,8 +31,9 @@ import {getColorByApp} from '../../chrome/mainsidebar/sidebarUtils';
|
||||
import Client from '../../Client';
|
||||
import {State} from '../../reducers';
|
||||
import {brandIcons} from '../../ui/components/colors';
|
||||
import {showEmulatorLauncher} from './LaunchEmulator';
|
||||
|
||||
const {Text} = Typography;
|
||||
const {Text, Link, Title} = Typography;
|
||||
|
||||
function getOsIcon(os?: OS) {
|
||||
switch (os) {
|
||||
@@ -86,7 +88,7 @@ export function AppSelector() {
|
||||
);
|
||||
const client = clients.find((client) => client.id === selectedApp);
|
||||
|
||||
return (
|
||||
return entries.length ? (
|
||||
<Radio.Group
|
||||
value={selectedApp}
|
||||
size="small"
|
||||
@@ -96,9 +98,7 @@ export function AppSelector() {
|
||||
}}>
|
||||
<Dropdown
|
||||
overlay={
|
||||
<Menu selectedKeys={selectedApp ? [selectedApp] : []}>
|
||||
{entries.flat()}
|
||||
</Menu>
|
||||
<Menu selectedKeys={selectedApp ? [selectedApp] : []}>{entries}</Menu>
|
||||
}>
|
||||
<AppInspectButton title="Select the device / app to inspect">
|
||||
<Layout.Horizontal gap center>
|
||||
@@ -114,6 +114,8 @@ export function AppSelector() {
|
||||
</AppInspectButton>
|
||||
</Dropdown>
|
||||
</Radio.Group>
|
||||
) : (
|
||||
<NoDevices />
|
||||
);
|
||||
}
|
||||
|
||||
@@ -216,5 +218,36 @@ function computeEntries(
|
||||
)),
|
||||
]);
|
||||
}
|
||||
return entries;
|
||||
return entries.flat();
|
||||
}
|
||||
|
||||
function NoDevices() {
|
||||
const store = useStore();
|
||||
|
||||
const onLaunchEmulator = useTrackedCallback(
|
||||
'select-emulator',
|
||||
() => {
|
||||
showEmulatorLauncher(store);
|
||||
},
|
||||
[],
|
||||
);
|
||||
|
||||
return (
|
||||
<Alert
|
||||
type="info"
|
||||
message={
|
||||
<>
|
||||
<Title level={4}>No devices found</Title>
|
||||
<Text>
|
||||
Start a fresh emulator <RocketOutlined onClick={onLaunchEmulator} />{' '}
|
||||
or check the{' '}
|
||||
<Link href="https://fbflipper.com/docs/troubleshooting">
|
||||
troubleshooting guide
|
||||
</Link>
|
||||
.
|
||||
</Text>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -8,12 +8,13 @@
|
||||
*/
|
||||
|
||||
import {
|
||||
useStore as useReduxStore,
|
||||
useSelector,
|
||||
shallowEqual,
|
||||
useDispatch as useDispatchBase,
|
||||
} from 'react-redux';
|
||||
import {Dispatch as ReduxDispatch} from 'redux';
|
||||
import {State, Actions} from '../reducers/index';
|
||||
import {State, Actions, Store} from '../reducers/index';
|
||||
|
||||
/**
|
||||
* Strongly typed wrapper or Redux's useSelector.
|
||||
@@ -22,9 +23,14 @@ import {State, Actions} from '../reducers/index';
|
||||
*/
|
||||
export function useStore<Selected>(
|
||||
selector: (state: State) => Selected,
|
||||
equalityFn: (left: Selected, right: Selected) => boolean = shallowEqual,
|
||||
): Selected {
|
||||
return useSelector(selector, equalityFn);
|
||||
equalityFn?: (left: Selected, right: Selected) => boolean,
|
||||
): Selected;
|
||||
export function useStore(): Store;
|
||||
export function useStore(selector?: any, equalityFn?: any) {
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
if (arguments.length === 0) return useReduxStore();
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
return useSelector(selector, equalityFn ?? shallowEqual);
|
||||
}
|
||||
|
||||
export type Dispatch = ReduxDispatch<Actions>;
|
||||
|
||||
Reference in New Issue
Block a user