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:
committed by
Facebook GitHub Bot
parent
9deed974be
commit
3484f321af
@@ -19,6 +19,7 @@ import {
|
||||
SettingOutlined,
|
||||
QuestionCircleOutlined,
|
||||
MedicineBoxOutlined,
|
||||
RocketOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import {SidebarLeft, SidebarRight} from './SandyIcons';
|
||||
import {useDispatch, useStore} from '../utils/useStore';
|
||||
@@ -37,6 +38,8 @@ import {useValue} from 'flipper-plugin';
|
||||
import {logout} 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';
|
||||
|
||||
const LeftRailButtonElem = styled(Button)<{kind?: 'small'}>(({kind}) => ({
|
||||
width: kind === 'small' ? 32 : 36,
|
||||
@@ -128,6 +131,7 @@ export function LeftRail({
|
||||
/>
|
||||
</Layout.Container>
|
||||
<Layout.Container center gap={10} padh={6}>
|
||||
<LaunchEmulatorButton />
|
||||
<SetupDoctorButton />
|
||||
<WelcomeScreenButton />
|
||||
<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() {
|
||||
const [visible, setVisible] = useState(false);
|
||||
const result = useStore(
|
||||
|
||||
@@ -8,13 +8,11 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import {Alert, Button, Input} from 'antd';
|
||||
import {Alert, Input} from 'antd';
|
||||
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 {theme} from 'flipper-plugin';
|
||||
import {useStore as useReduxStore} from 'react-redux';
|
||||
import {showEmulatorLauncher} from './LaunchEmulator';
|
||||
import {AppSelector} from './AppSelector';
|
||||
import {useStore} from '../../utils/useStore';
|
||||
import {PluginList} from './PluginList';
|
||||
@@ -33,8 +31,8 @@ const appTooltip = (
|
||||
);
|
||||
|
||||
export function AppInspect() {
|
||||
const store = useReduxStore();
|
||||
const selectedDevice = useStore((state) => state.connections.selectedDevice);
|
||||
const isArchived = !!selectedDevice?.isArchived;
|
||||
|
||||
return (
|
||||
<LeftSidebar>
|
||||
@@ -45,26 +43,27 @@ export function AppInspect() {
|
||||
</SidebarTitle>
|
||||
<Layout.Container padv="small" padh="medium" gap={theme.space.large}>
|
||||
<AppSelector />
|
||||
<Input addonAfter={<SettingOutlined />} defaultValue="mysite" />
|
||||
<Toolbar gap>
|
||||
<Button
|
||||
icon={<RocketOutlined />}
|
||||
type="ghost"
|
||||
title="Start Emulator / Simulator..."
|
||||
onClick={() => {
|
||||
showEmulatorLauncher(store);
|
||||
}}
|
||||
{isArchived ? (
|
||||
<Alert
|
||||
message="This device is a snapshot and cannot be interacted with."
|
||||
type="info"
|
||||
/>
|
||||
<MetroButton useSandy />
|
||||
<ScreenCaptureButtons useSandy />
|
||||
</Toolbar>
|
||||
) : (
|
||||
<Input addonAfter={<SettingOutlined />} defaultValue="mysite" />
|
||||
)}
|
||||
{!isArchived && (
|
||||
<Toolbar gap>
|
||||
<MetroButton useSandy />
|
||||
<ScreenCaptureButtons useSandy />
|
||||
</Toolbar>
|
||||
)}
|
||||
</Layout.Container>
|
||||
</Layout.Container>
|
||||
<Layout.ScrollContainer vertical padv={theme.space.large}>
|
||||
{selectedDevice ? (
|
||||
<PluginList />
|
||||
) : (
|
||||
<Alert message="No device or app selected" type="info" />
|
||||
<Alert message="No device or app selected." type="info" />
|
||||
)}
|
||||
</Layout.ScrollContainer>
|
||||
</Layout.Top>
|
||||
|
||||
@@ -59,6 +59,7 @@ export const PluginList = memo(function PluginList() {
|
||||
plugins,
|
||||
connections.userStarredPlugins,
|
||||
]);
|
||||
const isArchived = !!activeDevice?.isArchived;
|
||||
|
||||
const handleAppPluginClick = useCallback(
|
||||
(pluginId) => {
|
||||
@@ -122,20 +123,22 @@ export const PluginList = memo(function PluginList() {
|
||||
))}
|
||||
</PluginGroup>
|
||||
|
||||
<PluginGroup key="metro" title="React Native">
|
||||
{metroPlugins.map((plugin) => (
|
||||
<PluginEntry
|
||||
key={'metro' + plugin.id}
|
||||
plugin={plugin.details}
|
||||
active={
|
||||
plugin.id === connections.selectedPlugin &&
|
||||
connections.selectedDevice === metroDevice
|
||||
}
|
||||
onClick={handleMetroPluginClick}
|
||||
tooltip={getPluginTooltip(plugin.details)}
|
||||
/>
|
||||
))}
|
||||
</PluginGroup>
|
||||
{!isArchived && (
|
||||
<PluginGroup key="metro" title="React Native">
|
||||
{metroPlugins.map((plugin) => (
|
||||
<PluginEntry
|
||||
key={'metro' + plugin.id}
|
||||
plugin={plugin.details}
|
||||
active={
|
||||
plugin.id === connections.selectedPlugin &&
|
||||
connections.selectedDevice === metroDevice
|
||||
}
|
||||
onClick={handleMetroPluginClick}
|
||||
tooltip={getPluginTooltip(plugin.details)}
|
||||
/>
|
||||
))}
|
||||
</PluginGroup>
|
||||
)}
|
||||
<PluginGroup key="enabled" title="Enabled">
|
||||
{enabledPlugins.map((plugin) => (
|
||||
<PluginEntry
|
||||
@@ -145,48 +148,56 @@ export const PluginList = memo(function PluginList() {
|
||||
onClick={handleAppPluginClick}
|
||||
tooltip={getPluginTooltip(plugin.details)}
|
||||
actions={
|
||||
<ActionButton
|
||||
id={plugin.id}
|
||||
onClick={handleStarPlugin}
|
||||
title="Disable plugin"
|
||||
icon={<MinusOutlined size={16} style={{marginRight: 0}} />}
|
||||
/>
|
||||
isArchived ? null : (
|
||||
<ActionButton
|
||||
id={plugin.id}
|
||||
onClick={handleStarPlugin}
|
||||
title="Disable plugin"
|
||||
icon={
|
||||
<MinusOutlined size={16} style={{marginRight: 0}} />
|
||||
}
|
||||
/>
|
||||
)
|
||||
}
|
||||
/>
|
||||
))}
|
||||
</PluginGroup>
|
||||
<PluginGroup key="disabled" title="Disabled">
|
||||
{disabledPlugins.map((plugin) => (
|
||||
<PluginEntry
|
||||
key={plugin.id}
|
||||
plugin={plugin.details}
|
||||
active={plugin.id === connections.selectedPlugin}
|
||||
tooltip={getPluginTooltip(plugin.details)}
|
||||
actions={
|
||||
<ActionButton
|
||||
id={plugin.id}
|
||||
title="Enable plugin"
|
||||
onClick={handleStarPlugin}
|
||||
icon={<PlusOutlined size={16} style={{marginRight: 0}} />}
|
||||
/>
|
||||
}
|
||||
disabled
|
||||
/>
|
||||
))}
|
||||
</PluginGroup>
|
||||
<PluginGroup key="unavailable" title="Unavailable plugins">
|
||||
{unavailablePlugins.map(([plugin, reason]) => (
|
||||
<PluginEntry
|
||||
key={plugin.id}
|
||||
plugin={plugin}
|
||||
tooltip={`${getPluginTitle(plugin)} (${plugin.id}@${
|
||||
plugin.version
|
||||
}): ${reason}`}
|
||||
disabled
|
||||
actions={<InfoIcon>{reason}</InfoIcon>}
|
||||
/>
|
||||
))}
|
||||
</PluginGroup>
|
||||
{!isArchived && (
|
||||
<PluginGroup key="disabled" title="Disabled">
|
||||
{disabledPlugins.map((plugin) => (
|
||||
<PluginEntry
|
||||
key={plugin.id}
|
||||
plugin={plugin.details}
|
||||
active={plugin.id === connections.selectedPlugin}
|
||||
tooltip={getPluginTooltip(plugin.details)}
|
||||
actions={
|
||||
<ActionButton
|
||||
id={plugin.id}
|
||||
title="Enable plugin"
|
||||
onClick={handleStarPlugin}
|
||||
icon={<PlusOutlined size={16} style={{marginRight: 0}} />}
|
||||
/>
|
||||
}
|
||||
disabled
|
||||
/>
|
||||
))}
|
||||
</PluginGroup>
|
||||
)}
|
||||
{!isArchived && (
|
||||
<PluginGroup key="unavailable" title="Unavailable plugins">
|
||||
{unavailablePlugins.map(([plugin, reason]) => (
|
||||
<PluginEntry
|
||||
key={plugin.id}
|
||||
plugin={plugin}
|
||||
tooltip={`${getPluginTitle(plugin)} (${plugin.id}@${
|
||||
plugin.version
|
||||
}): ${reason}`}
|
||||
disabled
|
||||
actions={<InfoIcon>{reason}</InfoIcon>}
|
||||
/>
|
||||
))}
|
||||
</PluginGroup>
|
||||
)}
|
||||
</PluginMenu>
|
||||
</Layout.Container>
|
||||
</Layout.Container>
|
||||
@@ -231,7 +242,7 @@ const PluginEntry = memo(function PluginEntry({
|
||||
active?: boolean;
|
||||
tooltip: string;
|
||||
onClick?: (id: string) => void;
|
||||
actions?: React.ReactElement;
|
||||
actions?: React.ReactElement | null;
|
||||
}) {
|
||||
const [hovering, setHovering] = useState(false);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user