Put connection setup state in redux

Summary: Puts the connection state into redux so we have more visibility on what's happening in bug reports and in general allowing us to display it on screen.

Reviewed By: passy

Differential Revision: D13060455

fbshipit-source-id: c79b4b7d6a1155d86128a5d8d1174ead9e4514ae
This commit is contained in:
John Knox
2018-11-15 04:31:54 -08:00
committed by Facebook Github Bot
parent 6362188563
commit 866cb72124
4 changed files with 113 additions and 0 deletions

View File

@@ -0,0 +1,12 @@
/**
* 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 UninitializedClient = {
os: string,
deviceName: string,
appName: string,
};

View File

@@ -10,6 +10,7 @@ import Server from '../server.js';
import type {Store} from '../reducers/index.js';
import type Logger from '../fb-stubs/Logger.js';
import type Client from '../Client.js';
import type {UninitializedClient} from '../UninitializedClient';
export default (store: Store, logger: Logger) => {
const server = new Server(logger, store);
@@ -45,6 +46,33 @@ export default (store: Store, logger: Logger) => {
});
});
server.addListener('start-client-setup', (client: UninitializedClient) => {
store.dispatch({
type: 'START_CLIENT_SETUP',
payload: client,
});
});
server.addListener(
'finish-client-setup',
(payload: {client: UninitializedClient, deviceId: string}) => {
store.dispatch({
type: 'FINISH_CLIENT_SETUP',
payload: payload,
});
},
);
server.addListener(
'client-setup-error',
(payload: {client: UninitializedClient, error: Error}) => {
store.dispatch({
type: 'CLIENT_SETUP_ERROR',
payload: payload,
});
},
);
window.addEventListener('beforeunload', () => {
server.close();
});

View File

@@ -7,6 +7,8 @@
import type BaseDevice from '../devices/BaseDevice';
import type Client from '../Client';
import type {UninitializedClient} from '../UninitializedClient';
import {isEqual} from 'lodash';
export type State = {|
devices: Array<BaseDevice>,
@@ -19,6 +21,11 @@ export type State = {|
userPreferredApp: ?string,
error: ?string,
clients: Array<Client>,
uninitializedClients: Array<{
client: UninitializedClient,
deviceId?: string,
errorMessage?: string,
}>,
deepLinkPayload: ?string,
|};
@@ -66,6 +73,18 @@ export type Action =
| {
type: 'PREFER_DEVICE',
payload: string,
}
| {
type: 'START_CLIENT_SETUP',
payload: UninitializedClient,
}
| {
type: 'FINISH_CLIENT_SETUP',
payload: {client: UninitializedClient, deviceId: string},
}
| {
type: 'CLIENT_SETUP_ERROR',
payload: {client: UninitializedClient, error: Error},
};
const DEFAULT_PLUGIN = 'DeviceLogs';
@@ -81,6 +100,7 @@ const INITAL_STATE: State = {
userPreferredApp: null,
error: null,
clients: [],
uninitializedClients: [],
deepLinkPayload: null,
};
@@ -208,6 +228,12 @@ export default function reducer(
return {
...state,
clients: state.clients.concat(payload),
uninitializedClients: state.uninitializedClients.filter(c => {
return (
c.deviceId !== payload.query.device_id ||
c.client.appName !== payload.query.app
);
}),
selectedApp,
selectedPlugin,
};
@@ -237,6 +263,39 @@ export default function reducer(
const {payload} = action;
return {...state, error: payload};
}
case 'START_CLIENT_SETUP': {
const {payload} = action;
return {
...state,
uninitializedClients: state.uninitializedClients
.filter(entry => !isEqual(entry.client, payload))
.concat([{client: payload}]),
};
}
case 'FINISH_CLIENT_SETUP': {
const {payload} = action;
return {
...state,
uninitializedClients: state.uninitializedClients.map(
c =>
isEqual(c.client, payload.client)
? {...c, deviceId: payload.deviceId}
: c,
),
};
}
case 'CLIENT_SETUP_ERROR': {
const {payload} = action;
return {
...state,
uninitializedClients: state.uninitializedClients.map(
c =>
isEqual(c.client, payload.client)
? {...c, error: payload.error.message}
: c,
),
};
}
default:
return state;
}

View File

@@ -15,6 +15,7 @@ import {RSocketServer, ReactiveSocket} from 'rsocket-core';
import RSocketTCPServer from 'rsocket-tcp-server';
import {Single} from 'rsocket-flowable';
import Client from './Client.js';
import type {UninitializedClient} from './UninitializedClient';
import {RecurringError} from './utils/errors';
const EventEmitter = (require('events'): any);
@@ -140,6 +141,13 @@ export default class Server extends EventEmitter {
const clientData = JSON.parse(connectRequest.data);
this.connectionTracker.logConnectionAttempt(clientData);
const client: UninitializedClient = {
os: clientData.os,
deviceName: clientData.device,
appName: clientData.app,
};
this.emit('start-client-setup', client);
if (
clientData.os === 'iOS' &&
!clientData.device.toLowerCase().includes('simulator')
@@ -181,6 +189,7 @@ export default class Server extends EventEmitter {
|} = rawData;
if (json.method === 'signCertificate') {
console.debug('CSR received from device', 'server');
const {csr, destination} = json;
return new Single(subscriber => {
subscriber.onSubscribe();
@@ -193,10 +202,15 @@ export default class Server extends EventEmitter {
}),
metadata: '',
});
this.emit('finish-client-setup', {
client,
deviceId: result.deviceId,
});
})
.catch(e => {
console.error(e, 'server');
subscriber.onError(e);
this.emit('client-setup-error', {client, error: e});
});
});
}