Store use selected plugin after reconnect
Summary: Deselect plugin when app disconnects, but store the information that the users had the app selected. When the app conencts again, restore the user's selection. This also stores the device seleced by the user and reselects the device if it connects. Reviewed By: xiphirx Differential Revision: D8833948 fbshipit-source-id: ad3ef54681550ae674bdd4e695d677aea5c14588
This commit is contained in:
committed by
Pascal Hartig
parent
a8138984f9
commit
1f977f4844
@@ -71,8 +71,7 @@ export class App extends React.Component<Props> {
|
|||||||
export default connect(
|
export default connect(
|
||||||
({
|
({
|
||||||
application: {pluginManagerVisible, bugDialogVisible, leftSidebarVisible},
|
application: {pluginManagerVisible, bugDialogVisible, leftSidebarVisible},
|
||||||
connections: {selectedDevice},
|
connections: {selectedDevice, error},
|
||||||
server: {error},
|
|
||||||
}) => ({
|
}) => ({
|
||||||
pluginManagerVisible,
|
pluginManagerVisible,
|
||||||
bugDialogVisible,
|
bugDialogVisible,
|
||||||
|
|||||||
@@ -147,9 +147,8 @@ class PluginContainer extends Component<Props, State> {
|
|||||||
export default connect(
|
export default connect(
|
||||||
({
|
({
|
||||||
application: {rightSidebarVisible, rightSidebarAvailable},
|
application: {rightSidebarVisible, rightSidebarAvailable},
|
||||||
connections: {selectedPlugin, selectedDevice, selectedApp},
|
connections: {selectedPlugin, selectedDevice, selectedApp, clients},
|
||||||
pluginStates,
|
pluginStates,
|
||||||
server: {clients},
|
|
||||||
}) => ({
|
}) => ({
|
||||||
selectedPlugin,
|
selectedPlugin,
|
||||||
selectedDevice,
|
selectedDevice,
|
||||||
|
|||||||
@@ -7,8 +7,8 @@
|
|||||||
|
|
||||||
import {Component, Button} from 'sonar';
|
import {Component, Button} from 'sonar';
|
||||||
import {connect} from 'react-redux';
|
import {connect} from 'react-redux';
|
||||||
import {exec} from 'child_process';
|
import {spawn} from 'child_process';
|
||||||
import {selectDevice} from '../reducers/connections.js';
|
import {selectDevice, preferDevice} from '../reducers/connections.js';
|
||||||
import type BaseDevice from '../devices/BaseDevice.js';
|
import type BaseDevice from '../devices/BaseDevice.js';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
@@ -16,15 +16,21 @@ type Props = {
|
|||||||
androidEmulators: Array<string>,
|
androidEmulators: Array<string>,
|
||||||
devices: Array<BaseDevice>,
|
devices: Array<BaseDevice>,
|
||||||
selectDevice: (device: BaseDevice) => void,
|
selectDevice: (device: BaseDevice) => void,
|
||||||
|
preferDevice: (device: string) => void,
|
||||||
};
|
};
|
||||||
|
|
||||||
class DevicesButton extends Component<Props> {
|
class DevicesButton extends Component<Props> {
|
||||||
launchEmulator = (name: string) => {
|
launchEmulator = (name: string) => {
|
||||||
exec(`$ANDROID_HOME/tools/emulator @${name}`, error => {
|
const child = spawn(
|
||||||
if (error) {
|
`${process.env.ANDROID_HOME || ''}/tools/emulator`,
|
||||||
console.error(error);
|
[`@${name}`],
|
||||||
}
|
{
|
||||||
});
|
detached: true,
|
||||||
|
stdio: 'ignore',
|
||||||
|
},
|
||||||
|
);
|
||||||
|
child.on('error', console.error);
|
||||||
|
this.props.preferDevice(name);
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@@ -96,5 +102,5 @@ export default connect(
|
|||||||
androidEmulators,
|
androidEmulators,
|
||||||
selectedDevice,
|
selectedDevice,
|
||||||
}),
|
}),
|
||||||
{selectDevice},
|
{selectDevice, preferDevice},
|
||||||
)(DevicesButton);
|
)(DevicesButton);
|
||||||
|
|||||||
@@ -225,10 +225,7 @@ class MainSidebar extends Component<MainSidebarProps> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default connect(
|
export default connect(
|
||||||
({
|
({connections: {selectedDevice, selectedPlugin, selectedApp, clients}}) => ({
|
||||||
connections: {selectedDevice, selectedPlugin, selectedApp},
|
|
||||||
server: {clients},
|
|
||||||
}) => ({
|
|
||||||
selectedDevice,
|
selectedDevice,
|
||||||
selectedPlugin,
|
selectedPlugin,
|
||||||
selectedApp,
|
selectedApp,
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import Server from '../server.js';
|
|||||||
|
|
||||||
import type {Store} from '../reducers/index.js';
|
import type {Store} from '../reducers/index.js';
|
||||||
import type Logger from '../fb-stubs/Logger.js';
|
import type Logger from '../fb-stubs/Logger.js';
|
||||||
|
import type Client from '../Client.js';
|
||||||
|
|
||||||
export default (store: Store, logger: Logger) => {
|
export default (store: Store, logger: Logger) => {
|
||||||
const server = new Server(logger);
|
const server = new Server(logger);
|
||||||
|
|||||||
@@ -6,12 +6,19 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import type BaseDevice from '../devices/BaseDevice';
|
import type BaseDevice from '../devices/BaseDevice';
|
||||||
|
import type Client from '../Client';
|
||||||
|
|
||||||
export type State = {
|
export type State = {
|
||||||
devices: Array<BaseDevice>,
|
devices: Array<BaseDevice>,
|
||||||
androidEmulators: Array<string>,
|
androidEmulators: Array<string>,
|
||||||
selectedDevice: ?BaseDevice,
|
selectedDevice: ?BaseDevice,
|
||||||
selectedPlugin: ?string,
|
selectedPlugin: ?string,
|
||||||
selectedApp: ?string,
|
selectedApp: ?string,
|
||||||
|
userPreferredDevice: ?string,
|
||||||
|
userPreferredPlugin: ?string,
|
||||||
|
userPreferredApp: ?string,
|
||||||
|
error: ?string,
|
||||||
|
clients: Array<Client>,
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Action =
|
export type Action =
|
||||||
@@ -37,6 +44,22 @@ export type Action =
|
|||||||
selectedPlugin: ?string,
|
selectedPlugin: ?string,
|
||||||
selectedApp: ?string,
|
selectedApp: ?string,
|
||||||
},
|
},
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: 'SERVER_ERROR',
|
||||||
|
payload: ?string,
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: 'NEW_CLIENT',
|
||||||
|
payload: Client,
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: 'CLIENT_REMOVED',
|
||||||
|
payload: string,
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: 'PREFER_DEVICE',
|
||||||
|
payload: string,
|
||||||
};
|
};
|
||||||
|
|
||||||
const DEFAULT_PLUGIN = 'DeviceLogs';
|
const DEFAULT_PLUGIN = 'DeviceLogs';
|
||||||
@@ -47,6 +70,11 @@ const INITAL_STATE: State = {
|
|||||||
selectedDevice: null,
|
selectedDevice: null,
|
||||||
selectedApp: null,
|
selectedApp: null,
|
||||||
selectedPlugin: DEFAULT_PLUGIN,
|
selectedPlugin: DEFAULT_PLUGIN,
|
||||||
|
userPreferredDevice: null,
|
||||||
|
userPreferredPlugin: null,
|
||||||
|
userPreferredApp: null,
|
||||||
|
error: null,
|
||||||
|
clients: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function reducer(
|
export default function reducer(
|
||||||
@@ -61,6 +89,7 @@ export default function reducer(
|
|||||||
selectedApp: null,
|
selectedApp: null,
|
||||||
selectedPlugin: DEFAULT_PLUGIN,
|
selectedPlugin: DEFAULT_PLUGIN,
|
||||||
selectedDevice: payload,
|
selectedDevice: payload,
|
||||||
|
userPreferredDevice: payload.title,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
case 'REGISTER_ANDROID_EMULATORS': {
|
case 'REGISTER_ANDROID_EMULATORS': {
|
||||||
@@ -75,13 +104,17 @@ export default function reducer(
|
|||||||
const devices = state.devices.concat(payload);
|
const devices = state.devices.concat(payload);
|
||||||
let {selectedDevice} = state;
|
let {selectedDevice} = state;
|
||||||
let selection = {};
|
let selection = {};
|
||||||
|
|
||||||
if (!selectedDevice) {
|
if (!selectedDevice) {
|
||||||
selectedDevice = payload;
|
selectedDevice = payload;
|
||||||
selection = {
|
selection = {
|
||||||
selectedApp: null,
|
selectedApp: null,
|
||||||
selectedPlugin: DEFAULT_PLUGIN,
|
selectedPlugin: DEFAULT_PLUGIN,
|
||||||
};
|
};
|
||||||
|
} else if (payload.title === state.userPreferredDevice) {
|
||||||
|
selectedDevice = payload;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
devices,
|
devices,
|
||||||
@@ -127,8 +160,59 @@ export default function reducer(
|
|||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
...payload,
|
...payload,
|
||||||
|
userPreferredApp: payload.selectedApp,
|
||||||
|
userPreferredPlugin: payload.selectedPlugin,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 'NEW_CLIENT': {
|
||||||
|
const {payload} = action;
|
||||||
|
const {userPreferredApp, userPreferredPlugin} = state;
|
||||||
|
let {selectedApp, selectedPlugin} = state;
|
||||||
|
|
||||||
|
if (
|
||||||
|
userPreferredApp &&
|
||||||
|
userPreferredPlugin &&
|
||||||
|
payload.id === userPreferredApp &&
|
||||||
|
payload.plugins.includes(userPreferredPlugin)
|
||||||
|
) {
|
||||||
|
// user preferred client did reconnect, so let's select it
|
||||||
|
selectedApp = userPreferredApp;
|
||||||
|
selectedPlugin = userPreferredPlugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
clients: state.clients.concat(payload),
|
||||||
|
selectedApp,
|
||||||
|
selectedPlugin,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
case 'CLIENT_REMOVED': {
|
||||||
|
const {payload} = action;
|
||||||
|
|
||||||
|
let selected = {};
|
||||||
|
if (state.selectedApp === payload) {
|
||||||
|
selected.selectedApp = null;
|
||||||
|
selected.selectedPlugin = DEFAULT_PLUGIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
...selected,
|
||||||
|
clients: state.clients.filter(
|
||||||
|
(client: Client) => client.id !== payload,
|
||||||
|
),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
case 'PREFER_DEVICE': {
|
||||||
|
const {payload: userPreferredDevice} = action;
|
||||||
|
return {...state, userPreferredDevice};
|
||||||
|
}
|
||||||
|
case 'SERVER_ERROR': {
|
||||||
|
const {payload} = action;
|
||||||
|
return {...state, error: payload};
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
@@ -139,6 +223,11 @@ export const selectDevice = (payload: BaseDevice): Action => ({
|
|||||||
payload,
|
payload,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const preferDevice = (payload: string): Action => ({
|
||||||
|
type: 'PREFER_DEVICE',
|
||||||
|
payload,
|
||||||
|
});
|
||||||
|
|
||||||
export const selectPlugin = (payload: {
|
export const selectPlugin = (payload: {
|
||||||
selectedPlugin: ?string,
|
selectedPlugin: ?string,
|
||||||
selectedApp: ?string,
|
selectedApp: ?string,
|
||||||
|
|||||||
@@ -8,8 +8,8 @@
|
|||||||
import {combineReducers} from 'redux';
|
import {combineReducers} from 'redux';
|
||||||
import application from './application.js';
|
import application from './application.js';
|
||||||
import connections from './connections.js';
|
import connections from './connections.js';
|
||||||
import server from './server.js';
|
|
||||||
import pluginStates from './pluginStates.js';
|
import pluginStates from './pluginStates.js';
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
State as ApplicationState,
|
State as ApplicationState,
|
||||||
Action as ApplicationAction,
|
Action as ApplicationAction,
|
||||||
@@ -22,7 +22,6 @@ import type {
|
|||||||
State as PluginsState,
|
State as PluginsState,
|
||||||
Action as PluginsAction,
|
Action as PluginsAction,
|
||||||
} from './pluginStates.js';
|
} from './pluginStates.js';
|
||||||
import type {State as ServerState, Action as ServerAction} from './server.js';
|
|
||||||
import type {Store as ReduxStore} from 'redux';
|
import type {Store as ReduxStore} from 'redux';
|
||||||
|
|
||||||
export type Store = ReduxStore<
|
export type Store = ReduxStore<
|
||||||
@@ -30,14 +29,12 @@ export type Store = ReduxStore<
|
|||||||
application: ApplicationState,
|
application: ApplicationState,
|
||||||
connections: DevicesState,
|
connections: DevicesState,
|
||||||
pluginStates: PluginsState,
|
pluginStates: PluginsState,
|
||||||
server: ServerState,
|
|
||||||
},
|
},
|
||||||
ApplicationAction | DevicesAction | PluginsAction | ServerAction,
|
ApplicationAction | DevicesAction | PluginsAction,
|
||||||
>;
|
>;
|
||||||
|
|
||||||
export default combineReducers({
|
export default combineReducers({
|
||||||
application,
|
application,
|
||||||
connections,
|
connections,
|
||||||
pluginStates,
|
pluginStates,
|
||||||
server,
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,54 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright 2018-present Facebook.
|
|
||||||
* This source code is licensed under the MIT license found in the
|
|
||||||
* LICENSE file in the root directory of this source tree.
|
|
||||||
* @format
|
|
||||||
*/
|
|
||||||
|
|
||||||
export type State = {
|
|
||||||
error: ?string,
|
|
||||||
clients: Array<Client>,
|
|
||||||
};
|
|
||||||
|
|
||||||
export type Action =
|
|
||||||
| {
|
|
||||||
type: 'SERVER_ERROR',
|
|
||||||
payload: ?string,
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
type: 'NEW_CLIENT',
|
|
||||||
payload: Client,
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
type: 'CLIENT_REMOVED',
|
|
||||||
payload: string,
|
|
||||||
};
|
|
||||||
|
|
||||||
const INITIAL_STATE: State = {
|
|
||||||
error: null,
|
|
||||||
clients: [],
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function reducer(
|
|
||||||
state: State = INITIAL_STATE,
|
|
||||||
action: Action,
|
|
||||||
): State {
|
|
||||||
if (action.type === 'NEW_CLIENT') {
|
|
||||||
const {payload} = action;
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
clients: state.clients.concat(payload),
|
|
||||||
};
|
|
||||||
} else if (action.type === 'CLIENT_REMOVED') {
|
|
||||||
const {payload} = action;
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
clients: state.clients.filter((client: Client) => client.id !== payload),
|
|
||||||
};
|
|
||||||
} else if (action.type === 'SERVER_ERROR') {
|
|
||||||
const {payload} = action;
|
|
||||||
return {...state, error: payload};
|
|
||||||
} else {
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user