Support archived devices

Summary:
Make sure archived are displayed as such in the UI, and normal device functions aren't available:

* taking screenshots
* bookmarks
* metro device plugins
* disabling plugins
* disabled and unavailable plugins
* mobile builds

Also moved starting an emulator to the left rail, since it isn't a function related to the current selected thing

Reviewed By: cekkaewnumchai

Differential Revision: D24620247

fbshipit-source-id: f1f469e2fc5167fd90ccb35d583988873a9bc787
This commit is contained in:
Michel Weststrate
2020-10-30 04:20:00 -07:00
committed by Facebook GitHub Bot
parent 9deed974be
commit 3484f321af
3 changed files with 100 additions and 71 deletions

View File

@@ -19,6 +19,7 @@ import {
SettingOutlined, SettingOutlined,
QuestionCircleOutlined, QuestionCircleOutlined,
MedicineBoxOutlined, MedicineBoxOutlined,
RocketOutlined,
} from '@ant-design/icons'; } from '@ant-design/icons';
import {SidebarLeft, SidebarRight} from './SandyIcons'; import {SidebarLeft, SidebarRight} from './SandyIcons';
import {useDispatch, useStore} from '../utils/useStore'; import {useDispatch, useStore} from '../utils/useStore';
@@ -37,6 +38,8 @@ import {useValue} from 'flipper-plugin';
import {logout} from '../reducers/user'; import {logout} from '../reducers/user';
import config from '../fb-stubs/config'; import config from '../fb-stubs/config';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import {showEmulatorLauncher} from './appinspect/LaunchEmulator';
import {useStore as useReduxStore} from 'react-redux';
const LeftRailButtonElem = styled(Button)<{kind?: 'small'}>(({kind}) => ({ const LeftRailButtonElem = styled(Button)<{kind?: 'small'}>(({kind}) => ({
width: kind === 'small' ? 32 : 36, width: kind === 'small' ? 32 : 36,
@@ -128,6 +131,7 @@ export function LeftRail({
/> />
</Layout.Container> </Layout.Container>
<Layout.Container center gap={10} padh={6}> <Layout.Container center gap={10} padh={6}>
<LaunchEmulatorButton />
<SetupDoctorButton /> <SetupDoctorButton />
<WelcomeScreenButton /> <WelcomeScreenButton />
<ShowSettingsButton /> <ShowSettingsButton />
@@ -223,6 +227,21 @@ function DebugLogsButton({
); );
} }
function LaunchEmulatorButton() {
const store = useReduxStore();
return (
<LeftRailButton
icon={<RocketOutlined />}
title="Start Emulator / Simulator"
onClick={() => {
showEmulatorLauncher(store);
}}
small
/>
);
}
function SetupDoctorButton() { function SetupDoctorButton() {
const [visible, setVisible] = useState(false); const [visible, setVisible] = useState(false);
const result = useStore( const result = useStore(

View File

@@ -8,13 +8,11 @@
*/ */
import React from 'react'; import React from 'react';
import {Alert, Button, Input} from 'antd'; import {Alert, Input} from 'antd';
import {LeftSidebar, SidebarTitle, InfoIcon} from '../LeftSidebar'; import {LeftSidebar, SidebarTitle, InfoIcon} from '../LeftSidebar';
import {SettingOutlined, RocketOutlined} from '@ant-design/icons'; import {SettingOutlined} from '@ant-design/icons';
import {Layout, Link, styled} from '../../ui'; import {Layout, Link, styled} from '../../ui';
import {theme} from 'flipper-plugin'; import {theme} from 'flipper-plugin';
import {useStore as useReduxStore} from 'react-redux';
import {showEmulatorLauncher} from './LaunchEmulator';
import {AppSelector} from './AppSelector'; import {AppSelector} from './AppSelector';
import {useStore} from '../../utils/useStore'; import {useStore} from '../../utils/useStore';
import {PluginList} from './PluginList'; import {PluginList} from './PluginList';
@@ -33,8 +31,8 @@ const appTooltip = (
); );
export function AppInspect() { export function AppInspect() {
const store = useReduxStore();
const selectedDevice = useStore((state) => state.connections.selectedDevice); const selectedDevice = useStore((state) => state.connections.selectedDevice);
const isArchived = !!selectedDevice?.isArchived;
return ( return (
<LeftSidebar> <LeftSidebar>
@@ -45,26 +43,27 @@ export function AppInspect() {
</SidebarTitle> </SidebarTitle>
<Layout.Container padv="small" padh="medium" gap={theme.space.large}> <Layout.Container padv="small" padh="medium" gap={theme.space.large}>
<AppSelector /> <AppSelector />
<Input addonAfter={<SettingOutlined />} defaultValue="mysite" /> {isArchived ? (
<Toolbar gap> <Alert
<Button message="This device is a snapshot and cannot be interacted with."
icon={<RocketOutlined />} type="info"
type="ghost"
title="Start Emulator / Simulator..."
onClick={() => {
showEmulatorLauncher(store);
}}
/> />
) : (
<Input addonAfter={<SettingOutlined />} defaultValue="mysite" />
)}
{!isArchived && (
<Toolbar gap>
<MetroButton useSandy /> <MetroButton useSandy />
<ScreenCaptureButtons useSandy /> <ScreenCaptureButtons useSandy />
</Toolbar> </Toolbar>
)}
</Layout.Container> </Layout.Container>
</Layout.Container> </Layout.Container>
<Layout.ScrollContainer vertical padv={theme.space.large}> <Layout.ScrollContainer vertical padv={theme.space.large}>
{selectedDevice ? ( {selectedDevice ? (
<PluginList /> <PluginList />
) : ( ) : (
<Alert message="No device or app selected" type="info" /> <Alert message="No device or app selected." type="info" />
)} )}
</Layout.ScrollContainer> </Layout.ScrollContainer>
</Layout.Top> </Layout.Top>

View File

@@ -59,6 +59,7 @@ export const PluginList = memo(function PluginList() {
plugins, plugins,
connections.userStarredPlugins, connections.userStarredPlugins,
]); ]);
const isArchived = !!activeDevice?.isArchived;
const handleAppPluginClick = useCallback( const handleAppPluginClick = useCallback(
(pluginId) => { (pluginId) => {
@@ -122,6 +123,7 @@ export const PluginList = memo(function PluginList() {
))} ))}
</PluginGroup> </PluginGroup>
{!isArchived && (
<PluginGroup key="metro" title="React Native"> <PluginGroup key="metro" title="React Native">
{metroPlugins.map((plugin) => ( {metroPlugins.map((plugin) => (
<PluginEntry <PluginEntry
@@ -136,6 +138,7 @@ export const PluginList = memo(function PluginList() {
/> />
))} ))}
</PluginGroup> </PluginGroup>
)}
<PluginGroup key="enabled" title="Enabled"> <PluginGroup key="enabled" title="Enabled">
{enabledPlugins.map((plugin) => ( {enabledPlugins.map((plugin) => (
<PluginEntry <PluginEntry
@@ -145,16 +148,21 @@ export const PluginList = memo(function PluginList() {
onClick={handleAppPluginClick} onClick={handleAppPluginClick}
tooltip={getPluginTooltip(plugin.details)} tooltip={getPluginTooltip(plugin.details)}
actions={ actions={
isArchived ? null : (
<ActionButton <ActionButton
id={plugin.id} id={plugin.id}
onClick={handleStarPlugin} onClick={handleStarPlugin}
title="Disable plugin" title="Disable plugin"
icon={<MinusOutlined size={16} style={{marginRight: 0}} />} icon={
<MinusOutlined size={16} style={{marginRight: 0}} />
}
/> />
)
} }
/> />
))} ))}
</PluginGroup> </PluginGroup>
{!isArchived && (
<PluginGroup key="disabled" title="Disabled"> <PluginGroup key="disabled" title="Disabled">
{disabledPlugins.map((plugin) => ( {disabledPlugins.map((plugin) => (
<PluginEntry <PluginEntry
@@ -174,6 +182,8 @@ export const PluginList = memo(function PluginList() {
/> />
))} ))}
</PluginGroup> </PluginGroup>
)}
{!isArchived && (
<PluginGroup key="unavailable" title="Unavailable plugins"> <PluginGroup key="unavailable" title="Unavailable plugins">
{unavailablePlugins.map(([plugin, reason]) => ( {unavailablePlugins.map(([plugin, reason]) => (
<PluginEntry <PluginEntry
@@ -187,6 +197,7 @@ export const PluginList = memo(function PluginList() {
/> />
))} ))}
</PluginGroup> </PluginGroup>
)}
</PluginMenu> </PluginMenu>
</Layout.Container> </Layout.Container>
</Layout.Container> </Layout.Container>
@@ -231,7 +242,7 @@ const PluginEntry = memo(function PluginEntry({
active?: boolean; active?: boolean;
tooltip: string; tooltip: string;
onClick?: (id: string) => void; onClick?: (id: string) => void;
actions?: React.ReactElement; actions?: React.ReactElement | null;
}) { }) {
const [hovering, setHovering] = useState(false); const [hovering, setHovering] = useState(false);