Separate the concepts of archived and disconnected devices
Summary: Minor code cleanup to avoid future confusion: - archived: a device that was imported from a Flipper trace, and only has persisted state - (dis)connected: a real stateful device that might or might not have an active connection Reviewed By: nikoant Differential Revision: D26275459 fbshipit-source-id: eba554b37c39711e367c3795ff4456329a303c22
This commit is contained in:
committed by
Facebook GitHub Bot
parent
1bb1cae167
commit
43c68c0e7c
@@ -588,7 +588,7 @@ export default connect<StateFromProps, DispatchFromProps, OwnProps, Store>(
|
|||||||
}
|
}
|
||||||
const isArchivedDevice = !selectedDevice
|
const isArchivedDevice = !selectedDevice
|
||||||
? false
|
? false
|
||||||
: selectedDevice instanceof ArchivedDevice;
|
: selectedDevice.isArchived;
|
||||||
if (isArchivedDevice) {
|
if (isArchivedDevice) {
|
||||||
pluginIsEnabled = true;
|
pluginIsEnabled = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,10 +50,12 @@ test('Devices can disconnect', async () => {
|
|||||||
).toBe(true);
|
).toBe(true);
|
||||||
|
|
||||||
expect(device.isArchived).toBe(false);
|
expect(device.isArchived).toBe(false);
|
||||||
|
expect(device.connected.get()).toBe(true);
|
||||||
|
|
||||||
device.disconnect();
|
device.disconnect();
|
||||||
|
|
||||||
expect(device.isArchived).toBe(true);
|
expect(device.isArchived).toBe(false);
|
||||||
|
expect(device.connected.get()).toBe(false);
|
||||||
const instance = device.sandyPluginStates.get(deviceplugin.id)!;
|
const instance = device.sandyPluginStates.get(deviceplugin.id)!;
|
||||||
expect(instance.instanceApi.isConnected).toBe(false);
|
expect(instance.instanceApi.isConnected).toBe(false);
|
||||||
expect(instance).toBeTruthy();
|
expect(instance).toBeTruthy();
|
||||||
@@ -61,7 +63,8 @@ test('Devices can disconnect', async () => {
|
|||||||
expect(instance.instanceApi.destroy).toBeCalledTimes(0);
|
expect(instance.instanceApi.destroy).toBeCalledTimes(0);
|
||||||
|
|
||||||
device.destroy();
|
device.destroy();
|
||||||
expect(device.isArchived).toBe(true);
|
expect(device.isArchived).toBe(false);
|
||||||
|
expect(device.connected.get()).toBe(false);
|
||||||
expect(instance.instanceApi.destroy).toBeCalledTimes(1);
|
expect(instance.instanceApi.destroy).toBeCalledTimes(1);
|
||||||
|
|
||||||
expect(device.sandyPluginStates.get(deviceplugin.id)).toBeUndefined();
|
expect(device.sandyPluginStates.get(deviceplugin.id)).toBeUndefined();
|
||||||
@@ -91,6 +94,7 @@ test('New device with same serial removes & cleans the old one', async () => {
|
|||||||
const instance = device.sandyPluginStates.get(deviceplugin.id)!;
|
const instance = device.sandyPluginStates.get(deviceplugin.id)!;
|
||||||
|
|
||||||
expect(device.isArchived).toBe(false);
|
expect(device.isArchived).toBe(false);
|
||||||
|
expect(device.connected.get()).toBe(true);
|
||||||
expect(instance.instanceApi.destroy).toBeCalledTimes(0);
|
expect(instance.instanceApi.destroy).toBeCalledTimes(0);
|
||||||
expect(store.getState().connections.devices).toEqual([device]);
|
expect(store.getState().connections.devices).toEqual([device]);
|
||||||
|
|
||||||
@@ -107,7 +111,8 @@ test('New device with same serial removes & cleans the old one', async () => {
|
|||||||
});
|
});
|
||||||
device2.loadDevicePlugins(store.getState().plugins.devicePlugins);
|
device2.loadDevicePlugins(store.getState().plugins.devicePlugins);
|
||||||
|
|
||||||
expect(device.isArchived).toBe(true);
|
expect(device.isArchived).toBe(false);
|
||||||
|
expect(device.connected.get()).toBe(false);
|
||||||
expect(instance.instanceApi.destroy).toBeCalledTimes(1);
|
expect(instance.instanceApi.destroy).toBeCalledTimes(1);
|
||||||
expect(
|
expect(
|
||||||
device2.sandyPluginStates.get(deviceplugin.id)!.instanceApi.destroy,
|
device2.sandyPluginStates.get(deviceplugin.id)!.instanceApi.destroy,
|
||||||
|
|||||||
@@ -12,13 +12,12 @@ import MetroDevice, {MetroReportableEvent} from '../devices/MetroDevice';
|
|||||||
import {useStore} from '../utils/useStore';
|
import {useStore} from '../utils/useStore';
|
||||||
import {Button as AntButton} from 'antd';
|
import {Button as AntButton} from 'antd';
|
||||||
import {MenuOutlined, ReloadOutlined} from '@ant-design/icons';
|
import {MenuOutlined, ReloadOutlined} from '@ant-design/icons';
|
||||||
|
import {theme} from 'flipper-plugin';
|
||||||
type LogEntry = {};
|
|
||||||
|
|
||||||
export default function MetroButton() {
|
export default function MetroButton() {
|
||||||
const device = useStore((state) =>
|
const device = useStore((state) =>
|
||||||
state.connections.devices.find(
|
state.connections.devices.find(
|
||||||
(device) => device.os === 'Metro' && !device.isArchived,
|
(device) => device.os === 'Metro' && device.connected.get(),
|
||||||
),
|
),
|
||||||
) as MetroDevice | undefined;
|
) as MetroDevice | undefined;
|
||||||
|
|
||||||
@@ -69,6 +68,7 @@ export default function MetroButton() {
|
|||||||
sendCommand('reload');
|
sendCommand('reload');
|
||||||
}}
|
}}
|
||||||
loading={progress < 1}
|
loading={progress < 1}
|
||||||
|
style={{color: _hasBuildError ? theme.errorColor : undefined}}
|
||||||
/>
|
/>
|
||||||
<AntButton
|
<AntButton
|
||||||
icon={<MenuOutlined />}
|
icon={<MenuOutlined />}
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ import {OS, DeviceShell} from './BaseDevice';
|
|||||||
import {SupportFormRequestDetailsState} from '../reducers/supportForm';
|
import {SupportFormRequestDetailsState} from '../reducers/supportForm';
|
||||||
|
|
||||||
export default class ArchivedDevice extends BaseDevice {
|
export default class ArchivedDevice extends BaseDevice {
|
||||||
|
isArchived = true;
|
||||||
|
|
||||||
constructor(options: {
|
constructor(options: {
|
||||||
serial: string;
|
serial: string;
|
||||||
deviceType: DeviceType;
|
deviceType: DeviceType;
|
||||||
@@ -23,7 +25,7 @@ export default class ArchivedDevice extends BaseDevice {
|
|||||||
supportRequestDetails?: SupportFormRequestDetailsState;
|
supportRequestDetails?: SupportFormRequestDetailsState;
|
||||||
}) {
|
}) {
|
||||||
super(options.serial, options.deviceType, options.title, options.os);
|
super(options.serial, options.deviceType, options.title, options.os);
|
||||||
this.archivedState.set(true);
|
this.connected.set(false);
|
||||||
this.source = options.source || '';
|
this.source = options.source || '';
|
||||||
this.supportRequestDetails = options.supportRequestDetails;
|
this.supportRequestDetails = options.supportRequestDetails;
|
||||||
this.archivedScreenshotHandle = options.screenshotHandle;
|
this.archivedScreenshotHandle = options.screenshotHandle;
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ export type DeviceExport = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default class BaseDevice {
|
export default class BaseDevice {
|
||||||
|
isArchived = false;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
serial: string,
|
serial: string,
|
||||||
deviceType: DeviceType,
|
deviceType: DeviceType,
|
||||||
@@ -72,10 +74,7 @@ export default class BaseDevice {
|
|||||||
|
|
||||||
logListeners: Map<Symbol, DeviceLogListener> = new Map();
|
logListeners: Map<Symbol, DeviceLogListener> = new Map();
|
||||||
|
|
||||||
archivedState = createState(false);
|
readonly connected = createState(true);
|
||||||
get isArchived() {
|
|
||||||
return this.archivedState.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
// if imported, stores the original source location
|
// if imported, stores the original source location
|
||||||
source = '';
|
source = '';
|
||||||
@@ -93,7 +92,7 @@ export default class BaseDevice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
displayTitle(): string {
|
displayTitle(): string {
|
||||||
return this.title;
|
return this.connected.get() ? this.title : `${this.title} (Offline)`;
|
||||||
}
|
}
|
||||||
|
|
||||||
async exportState(
|
async exportState(
|
||||||
@@ -226,7 +225,7 @@ export default class BaseDevice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
disconnect() {
|
disconnect() {
|
||||||
this.archivedState.set(true);
|
this.connected.set(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy() {
|
destroy() {
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ export default class IOSDevice extends BaseDevice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async screenshot(): Promise<Buffer> {
|
async screenshot(): Promise<Buffer> {
|
||||||
if (this.isArchived) {
|
if (!this.connected.get()) {
|
||||||
return Buffer.from([]);
|
return Buffer.from([]);
|
||||||
}
|
}
|
||||||
const tmpImageName = uuid() + '.png';
|
const tmpImageName = uuid() + '.png';
|
||||||
@@ -192,7 +192,7 @@ export default class IOSDevice extends BaseDevice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async screenCaptureAvailable() {
|
async screenCaptureAvailable() {
|
||||||
return this.deviceType === 'emulator' && !this.isArchived;
|
return this.deviceType === 'emulator' && this.connected.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
async startScreenCapture(destination: string) {
|
async startScreenCapture(destination: string) {
|
||||||
|
|||||||
@@ -9,7 +9,6 @@
|
|||||||
|
|
||||||
import {LogLevel} from 'flipper-plugin';
|
import {LogLevel} from 'flipper-plugin';
|
||||||
import BaseDevice from './BaseDevice';
|
import BaseDevice from './BaseDevice';
|
||||||
import ArchivedDevice from './ArchivedDevice';
|
|
||||||
import {EventEmitter} from 'events';
|
import {EventEmitter} from 'events';
|
||||||
|
|
||||||
// From xplat/js/metro/packages/metro/src/lib/reporting.js
|
// From xplat/js/metro/packages/metro/src/lib/reporting.js
|
||||||
@@ -198,14 +197,4 @@ export default class MetroDevice extends BaseDevice {
|
|||||||
console.warn('Cannot send command, no connection', command);
|
console.warn('Cannot send command, no connection', command);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
archive() {
|
|
||||||
return new ArchivedDevice({
|
|
||||||
serial: this.serial,
|
|
||||||
deviceType: this.deviceType,
|
|
||||||
title: this.title,
|
|
||||||
os: this.os,
|
|
||||||
screenshotHandle: null,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -231,7 +231,7 @@ export default (store: Store, logger: Logger) => {
|
|||||||
.getState()
|
.getState()
|
||||||
.connections.devices.filter(
|
.connections.devices.filter(
|
||||||
(device: BaseDevice) =>
|
(device: BaseDevice) =>
|
||||||
device.serial === androidDevice.serial && device.isArchived,
|
device.serial === androidDevice.serial && !device.connected.get(),
|
||||||
)
|
)
|
||||||
.map((device) => device.serial);
|
.map((device) => device.serial);
|
||||||
|
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ function processDevices(
|
|||||||
(device) =>
|
(device) =>
|
||||||
device instanceof IOSDevice &&
|
device instanceof IOSDevice &&
|
||||||
device.deviceType === type &&
|
device.deviceType === type &&
|
||||||
!device.isArchived,
|
device.connected.get(),
|
||||||
)
|
)
|
||||||
.map((device) => device.serial),
|
.map((device) => device.serial),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -41,17 +41,8 @@ test('register, remove, re-register a metro device works correctly', () => {
|
|||||||
expect(state.devices.length).toBe(1);
|
expect(state.devices.length).toBe(1);
|
||||||
expect(state.devices[0].displayTitle()).toBe('React Native');
|
expect(state.devices[0].displayTitle()).toBe('React Native');
|
||||||
|
|
||||||
const archived = device1.archive();
|
device1.disconnect();
|
||||||
state = reducer(state, {
|
|
||||||
type: 'UNREGISTER_DEVICES',
|
|
||||||
payload: new Set([device1.serial]),
|
|
||||||
});
|
|
||||||
expect(state.devices.length).toBe(0);
|
|
||||||
|
|
||||||
state = reducer(state, {
|
|
||||||
type: 'REGISTER_DEVICE',
|
|
||||||
payload: archived,
|
|
||||||
});
|
|
||||||
expect(state.devices.length).toBe(1);
|
expect(state.devices.length).toBe(1);
|
||||||
expect(state.devices[0].displayTitle()).toBe('React Native (Offline)');
|
expect(state.devices[0].displayTitle()).toBe('React Native (Offline)');
|
||||||
|
|
||||||
@@ -61,6 +52,7 @@ test('register, remove, re-register a metro device works correctly', () => {
|
|||||||
});
|
});
|
||||||
expect(state.devices.length).toBe(1);
|
expect(state.devices.length).toBe(1);
|
||||||
expect(state.devices[0].displayTitle()).toBe('React Native');
|
expect(state.devices[0].displayTitle()).toBe('React Native');
|
||||||
|
expect(state.devices[0]).not.toBe(device1);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('triggering REGISTER_DEVICE before REGISTER_PLUGINS still registers device plugins', () => {
|
test('triggering REGISTER_DEVICE before REGISTER_PLUGINS still registers device plugins', () => {
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ import Client from '../../Client';
|
|||||||
import {State} from '../../reducers';
|
import {State} from '../../reducers';
|
||||||
import BaseDevice from '../../devices/BaseDevice';
|
import BaseDevice from '../../devices/BaseDevice';
|
||||||
import MetroDevice from '../../devices/MetroDevice';
|
import MetroDevice from '../../devices/MetroDevice';
|
||||||
import ArchivedDevice from '../../devices/ArchivedDevice';
|
|
||||||
import {ExclamationCircleOutlined, FieldTimeOutlined} from '@ant-design/icons';
|
import {ExclamationCircleOutlined, FieldTimeOutlined} from '@ant-design/icons';
|
||||||
|
|
||||||
const {Text} = Typography;
|
const {Text} = Typography;
|
||||||
@@ -56,7 +55,7 @@ export function AppInspect() {
|
|||||||
metroDevice,
|
metroDevice,
|
||||||
connections.userPreferredDevice,
|
connections.userPreferredDevice,
|
||||||
]);
|
]);
|
||||||
const isDeviceArchived = useValue(activeDevice?.archivedState, false);
|
const isDeviceConnected = useValue(activeDevice?.connected, false);
|
||||||
const isAppConnected = useValue(client?.connected, false);
|
const isAppConnected = useValue(client?.connected, false);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -69,13 +68,13 @@ export function AppInspect() {
|
|||||||
<Layout.Container padv="small" padh="medium" gap={theme.space.large}>
|
<Layout.Container padv="small" padh="medium" gap={theme.space.large}>
|
||||||
<AppSelector />
|
<AppSelector />
|
||||||
{renderStatusMessage(
|
{renderStatusMessage(
|
||||||
isDeviceArchived,
|
isDeviceConnected,
|
||||||
activeDevice,
|
activeDevice,
|
||||||
client,
|
client,
|
||||||
isAppConnected,
|
isAppConnected,
|
||||||
)}
|
)}
|
||||||
{!isDeviceArchived && isAppConnected && <BookmarkSection />}
|
{isDeviceConnected && isAppConnected && <BookmarkSection />}
|
||||||
{!isDeviceArchived && activeDevice && (
|
{isDeviceConnected && activeDevice && (
|
||||||
<Toolbar gap>
|
<Toolbar gap>
|
||||||
<MetroButton />
|
<MetroButton />
|
||||||
<ScreenCaptureButtons />
|
<ScreenCaptureButtons />
|
||||||
@@ -145,13 +144,28 @@ export function findBestDevice(
|
|||||||
}
|
}
|
||||||
|
|
||||||
function renderStatusMessage(
|
function renderStatusMessage(
|
||||||
isDeviceArchived: boolean,
|
isDeviceConnected: boolean,
|
||||||
activeDevice: BaseDevice | undefined,
|
activeDevice: BaseDevice | undefined,
|
||||||
client: Client | undefined,
|
client: Client | undefined,
|
||||||
isAppConnected: boolean,
|
isAppConnected: boolean,
|
||||||
): React.ReactNode {
|
): React.ReactNode {
|
||||||
return isDeviceArchived ? (
|
if (!activeDevice) {
|
||||||
activeDevice instanceof ArchivedDevice ? (
|
return (
|
||||||
|
<Layout.Horizontal gap center>
|
||||||
|
<ExclamationCircleOutlined style={{color: theme.warningColor}} />
|
||||||
|
<Text
|
||||||
|
type="secondary"
|
||||||
|
style={{
|
||||||
|
textTransform: 'uppercase',
|
||||||
|
fontSize: '0.8em',
|
||||||
|
}}>
|
||||||
|
Device disconnected
|
||||||
|
</Text>
|
||||||
|
</Layout.Horizontal>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return !isDeviceConnected ? (
|
||||||
|
activeDevice.isArchived ? (
|
||||||
<Layout.Horizontal gap center>
|
<Layout.Horizontal gap center>
|
||||||
<FieldTimeOutlined style={{color: theme.primaryColor}} />
|
<FieldTimeOutlined style={{color: theme.primaryColor}} />
|
||||||
<Text
|
<Text
|
||||||
@@ -160,7 +174,7 @@ function renderStatusMessage(
|
|||||||
textTransform: 'uppercase',
|
textTransform: 'uppercase',
|
||||||
fontSize: '0.8em',
|
fontSize: '0.8em',
|
||||||
}}>
|
}}>
|
||||||
Device loaded from file
|
No device selected
|
||||||
</Text>
|
</Text>
|
||||||
</Layout.Horizontal>
|
</Layout.Horizontal>
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ export function AppSelector() {
|
|||||||
uninitializedClients,
|
uninitializedClients,
|
||||||
selectedApp,
|
selectedApp,
|
||||||
} = useStore((state) => state.connections);
|
} = useStore((state) => state.connections);
|
||||||
useValue(selectedDevice?.archivedState, false); // subscribe to future archived state changes
|
useValue(selectedDevice?.connected, false); // subscribe to future archived state changes
|
||||||
|
|
||||||
const onSelectDevice = useTrackedCallback(
|
const onSelectDevice = useTrackedCallback(
|
||||||
'select-device',
|
'select-device',
|
||||||
@@ -223,8 +223,8 @@ function computeEntries(
|
|||||||
}
|
}
|
||||||
|
|
||||||
function DeviceTitle({device}: {device: BaseDevice}) {
|
function DeviceTitle({device}: {device: BaseDevice}) {
|
||||||
const connected = !useValue(device.archivedState);
|
const connected = useValue(device.connected);
|
||||||
const isImported = device instanceof ArchivedDevice;
|
const isImported = device.isArchived;
|
||||||
return (
|
return (
|
||||||
<span>
|
<span>
|
||||||
<>{device.title} </>
|
<>{device.title} </>
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ export const PluginList = memo(function PluginList({
|
|||||||
connections.userStarredPlugins,
|
connections.userStarredPlugins,
|
||||||
pluginsChanged,
|
pluginsChanged,
|
||||||
]);
|
]);
|
||||||
const isArchived = useValue(activeDevice?.archivedState, false);
|
const isConnected = useValue(activeDevice?.connected, false);
|
||||||
|
|
||||||
const annotatedDownloadablePlugins = useMemoize<
|
const annotatedDownloadablePlugins = useMemoize<
|
||||||
[
|
[
|
||||||
@@ -198,7 +198,7 @@ export const PluginList = memo(function PluginList({
|
|||||||
))}
|
))}
|
||||||
</PluginGroup>
|
</PluginGroup>
|
||||||
|
|
||||||
{!isArchived && (
|
{isConnected && (
|
||||||
<PluginGroup
|
<PluginGroup
|
||||||
key="metro"
|
key="metro"
|
||||||
title="React Native"
|
title="React Native"
|
||||||
@@ -226,7 +226,7 @@ export const PluginList = memo(function PluginList({
|
|||||||
onClick={handleAppPluginClick}
|
onClick={handleAppPluginClick}
|
||||||
tooltip={getPluginTooltip(plugin.details)}
|
tooltip={getPluginTooltip(plugin.details)}
|
||||||
actions={
|
actions={
|
||||||
isArchived ? null : (
|
isConnected ? (
|
||||||
<ActionButton
|
<ActionButton
|
||||||
id={plugin.id}
|
id={plugin.id}
|
||||||
onClick={handleStarPlugin}
|
onClick={handleStarPlugin}
|
||||||
@@ -235,12 +235,12 @@ export const PluginList = memo(function PluginList({
|
|||||||
<MinusOutlined size={16} style={{marginRight: 0}} />
|
<MinusOutlined size={16} style={{marginRight: 0}} />
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
)
|
) : null
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</PluginGroup>
|
</PluginGroup>
|
||||||
{!isArchived && (
|
{isConnected && (
|
||||||
<PluginGroup
|
<PluginGroup
|
||||||
key="disabled"
|
key="disabled"
|
||||||
title="Disabled"
|
title="Disabled"
|
||||||
@@ -305,7 +305,7 @@ export const PluginList = memo(function PluginList({
|
|||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</PluginGroup>
|
</PluginGroup>
|
||||||
{!isArchived && (
|
{isConnected && (
|
||||||
<PluginGroup
|
<PluginGroup
|
||||||
key="unavailable"
|
key="unavailable"
|
||||||
title="Unavailable plugins"
|
title="Unavailable plugins"
|
||||||
|
|||||||
@@ -431,14 +431,14 @@ export async function processStore(
|
|||||||
statusUpdate = () => {};
|
statusUpdate = () => {};
|
||||||
}
|
}
|
||||||
statusUpdate('Capturing screenshot...');
|
statusUpdate('Capturing screenshot...');
|
||||||
const deviceScreenshot = device.isArchived
|
const deviceScreenshot = device.connected.get()
|
||||||
? null
|
? await capture(device).catch((e) => {
|
||||||
: await capture(device).catch((e) => {
|
|
||||||
console.warn(
|
console.warn(
|
||||||
'Failed to capture device screenshot when exporting. ' + e,
|
'Failed to capture device screenshot when exporting. ' + e,
|
||||||
);
|
);
|
||||||
return null;
|
return null;
|
||||||
});
|
})
|
||||||
|
: null;
|
||||||
const processedClients = processClients(clients, serial, statusUpdate);
|
const processedClients = processClients(clients, serial, statusUpdate);
|
||||||
const processedPluginStates = processPluginStates({
|
const processedPluginStates = processPluginStates({
|
||||||
clients: processedClients,
|
clients: processedClients,
|
||||||
|
|||||||
@@ -301,7 +301,7 @@ function getFavoritePlugins(
|
|||||||
starredPlugins: undefined | string[],
|
starredPlugins: undefined | string[],
|
||||||
returnFavoredPlugins: boolean, // if false, unfavoried plugins are returned
|
returnFavoredPlugins: boolean, // if false, unfavoried plugins are returned
|
||||||
): PluginDefinition[] {
|
): PluginDefinition[] {
|
||||||
if (device instanceof ArchivedDevice) {
|
if (device.isArchived) {
|
||||||
if (!returnFavoredPlugins) {
|
if (!returnFavoredPlugins) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ export function getFileName(extension: 'png' | 'mp4'): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function capture(device: BaseDevice): Promise<string> {
|
export async function capture(device: BaseDevice): Promise<string> {
|
||||||
if (device.isArchived) {
|
if (!device.connected.get()) {
|
||||||
console.log('Skipping screenshot for archived device');
|
console.log('Skipping screenshot for disconnected device');
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
const pngPath = path.join(CAPTURE_LOCATION, getFileName('png'));
|
const pngPath = path.join(CAPTURE_LOCATION, getFileName('png'));
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import {SandyPluginDefinition} from './SandyPluginDefinition';
|
|||||||
import {BasePluginInstance, BasePluginClient} from './PluginBase';
|
import {BasePluginInstance, BasePluginClient} from './PluginBase';
|
||||||
import {FlipperLib} from './FlipperLib';
|
import {FlipperLib} from './FlipperLib';
|
||||||
import {DeviceType as PluginDeviceType} from 'flipper-plugin-lib';
|
import {DeviceType as PluginDeviceType} from 'flipper-plugin-lib';
|
||||||
|
import {Atom} from '../state/atom';
|
||||||
|
|
||||||
export type DeviceLogListener = (entry: DeviceLogEntry) => void;
|
export type DeviceLogListener = (entry: DeviceLogEntry) => void;
|
||||||
|
|
||||||
@@ -67,6 +68,7 @@ export interface RealFlipperDevice {
|
|||||||
os: string;
|
os: string;
|
||||||
serial: string;
|
serial: string;
|
||||||
isArchived: boolean;
|
isArchived: boolean;
|
||||||
|
connected: Atom<boolean>;
|
||||||
deviceType: DeviceType;
|
deviceType: DeviceType;
|
||||||
addLogListener(callback: DeviceLogListener): Symbol;
|
addLogListener(callback: DeviceLogListener): Symbol;
|
||||||
removeLogListener(id: Symbol): void;
|
removeLogListener(id: Symbol): void;
|
||||||
|
|||||||
@@ -136,8 +136,7 @@ export abstract class BasePluginInstance {
|
|||||||
return realDevice.isArchived;
|
return realDevice.isArchived;
|
||||||
},
|
},
|
||||||
get isConnected() {
|
get isConnected() {
|
||||||
// for now same as isArchived, in the future we might distinguish between archived/imported and disconnected/offline devices
|
return realDevice.connected.get();
|
||||||
return !realDevice.isArchived;
|
|
||||||
},
|
},
|
||||||
deviceType: realDevice.deviceType,
|
deviceType: realDevice.deviceType,
|
||||||
|
|
||||||
|
|||||||
@@ -421,6 +421,7 @@ function createMockDevice(options?: StartPluginOptions): RealFlipperDevice {
|
|||||||
deviceType: 'emulator',
|
deviceType: 'emulator',
|
||||||
serial: 'serial-000',
|
serial: 'serial-000',
|
||||||
isArchived: !!options?.isArchived,
|
isArchived: !!options?.isArchived,
|
||||||
|
connected: createState(true),
|
||||||
devicePlugins: [],
|
devicePlugins: [],
|
||||||
addLogListener(cb) {
|
addLogListener(cb) {
|
||||||
logListeners.push(cb);
|
logListeners.push(cb);
|
||||||
|
|||||||
Reference in New Issue
Block a user