Yarn workspaces

Summary:
1) moved "sonar/desktop/src" to "sonar/desktop/app/src", so "app" is now a separate package containing the core Flipper app code
2) Configured yarn workspaces with the root in "sonar/desktop": app, static, pkg, doctor, headless-tests. Plugins are not included for now, I plan to do this later.

Reviewed By: jknoxville

Differential Revision: D20535782

fbshipit-source-id: 600b2301960f37c7d72166e0d04eba462bec9fc1
This commit is contained in:
Anton Nikolaev
2020-03-20 13:31:37 -07:00
committed by Facebook GitHub Bot
parent 676d7bbd24
commit 863f89351e
340 changed files with 1635 additions and 294 deletions

View File

@@ -0,0 +1,217 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/
import {Button, styled} from 'flipper';
import {connect, ReactReduxContext} from 'react-redux';
import {spawn} from 'child_process';
import {dirname} from 'path';
import {selectDevice, preferDevice} from '../reducers/connections';
import {
setActiveSheet,
ActiveSheet,
ACTIVE_SHEET_JS_EMULATOR_LAUNCHER,
} from '../reducers/application';
import {default as which} from 'which';
import {showOpenDialog} from '../utils/exportData';
import BaseDevice from '../devices/BaseDevice';
import React, {Component} from 'react';
import {State} from '../reducers';
import GK from '../fb-stubs/GK';
type StateFromProps = {
selectedDevice: BaseDevice | null | undefined;
androidEmulators: Array<string>;
devices: Array<BaseDevice>;
};
type DispatchFromProps = {
selectDevice: (device: BaseDevice) => void;
preferDevice: (device: string) => void;
setActiveSheet: (sheet: ActiveSheet) => void;
};
type OwnProps = {};
type Props = OwnProps & StateFromProps & DispatchFromProps;
const DropdownButton = styled(Button)({
fontSize: 11,
});
class DevicesButton extends Component<Props> {
launchEmulator = (name: string) => {
// On Linux, you must run the emulator from the directory it's in because
// reasons ...
which('emulator')
.then(emulatorPath => {
if (emulatorPath) {
const child = spawn(emulatorPath, [`@${name}`], {
detached: true,
cwd: dirname(emulatorPath),
});
child.stderr.on('data', data => {
console.error(`Android emulator error: ${data}`);
});
child.on('error', console.error);
} else {
throw new Error('Could not get emulator path');
}
})
.catch(console.error);
this.props.preferDevice(name);
};
render() {
const {
devices,
androidEmulators,
selectedDevice,
selectDevice,
} = this.props;
let buttonLabel = 'No device selected';
let icon = 'minus-circle';
if (selectedDevice && selectedDevice.isArchived) {
buttonLabel = `${selectedDevice.displayTitle() || 'Unknown device'}`;
icon = 'box';
} else if (selectedDevice && selectedDevice.deviceType === 'physical') {
buttonLabel = selectedDevice.displayTitle() || 'Unknown device';
icon = 'mobile';
} else if (selectedDevice && selectedDevice.deviceType === 'emulator') {
buttonLabel = selectedDevice.displayTitle() || 'Unknown emulator';
icon = 'desktop';
}
const dropdown: any[] = [];
// Physical devices
const connectedDevices = [
{
label: 'Connected Devices',
enabled: false,
},
...devices
.filter(device => device.deviceType === 'physical')
.map((device: BaseDevice) => ({
click: () => selectDevice(device),
checked: device === selectedDevice,
label: `📱 ${device.displayTitle()}`,
type: 'checkbox',
})),
];
if (connectedDevices.length > 1) {
dropdown.push(...connectedDevices);
}
// Emulators
const runningEmulators = [
{
label: 'Running Emulators',
enabled: false,
},
...devices
.filter(device => device.deviceType === 'emulator')
.map((device: BaseDevice) => ({
click: () => selectDevice(device),
checked: device === selectedDevice,
label: device.displayTitle(),
type: 'checkbox',
})),
];
if (runningEmulators.length > 1) {
dropdown.push(...runningEmulators);
}
// Archived
const importedFiles = [
{
label: 'Disconnected Devices',
enabled: false,
},
...devices
.filter(device => device.isArchived)
.map((device: BaseDevice) => ({
click: () => selectDevice(device),
checked: device === selectedDevice,
label: `📦 ${device.displayTitle()}`,
type: 'checkbox',
})),
];
if (importedFiles.length > 1) {
dropdown.push(...importedFiles);
}
// Launch JS emulator
if (GK.get('flipper_js_client_emulator')) {
dropdown.push(
{type: 'separator' as 'separator'},
{
label: 'Launch JS Web App',
click: () =>
this.props.setActiveSheet(ACTIVE_SHEET_JS_EMULATOR_LAUNCHER),
},
);
}
// Launch Android emulators
if (androidEmulators.length > 0) {
const emulators = Array.from(androidEmulators)
.filter(
(name: string) =>
devices.findIndex(
(device: BaseDevice) =>
device.title === name && !device.isArchived,
) === -1,
)
.map((name: string) => ({
label: name,
click: () => this.launchEmulator(name),
}));
if (emulators.length > 0) {
dropdown.push(
{type: 'separator' as 'separator'},
{
label: 'Launch Android emulators',
enabled: false,
},
...emulators,
);
}
}
if (dropdown.length > 0) {
dropdown.push({type: 'separator' as 'separator'});
}
return (
<ReactReduxContext.Consumer>
{({store}) => {
dropdown.push({
label: 'Open File...',
click: () => {
showOpenDialog(store);
},
});
return (
<DropdownButton compact={true} icon={icon} dropdown={dropdown}>
{buttonLabel}
</DropdownButton>
);
}}
</ReactReduxContext.Consumer>
);
}
}
export default connect<StateFromProps, DispatchFromProps, OwnProps, State>(
({connections: {devices, androidEmulators, selectedDevice}}) => ({
devices,
androidEmulators,
selectedDevice,
}),
{
selectDevice,
preferDevice,
setActiveSheet,
},
)(DevicesButton);