Expose current connection status to Sandy plugins
Summary: Introduced `isConnected` flag on device and plugin client to reflect whether a connection is still available for the plugins, or that they have been disconnected. Potentially we could expose the (readonly) `connected` state atom for this as well, or an `onDisconnect` event for device pugins, to create a responsive UI, but there might be no need for that, in which case this suffices. Reviewed By: nikoant Differential Revision: D26249346 fbshipit-source-id: b8486713fdf2fcd520488ce54f771bd038fd13f8
This commit is contained in:
committed by
Facebook GitHub Bot
parent
7e1bf0f58b
commit
bb529411b5
@@ -36,6 +36,7 @@ export type LogLevel =
|
||||
export interface Device {
|
||||
readonly realDevice: any; // TODO: temporarily, clean up T70688226
|
||||
readonly isArchived: boolean;
|
||||
readonly isConnected: boolean;
|
||||
readonly os: string;
|
||||
readonly deviceType: DeviceType;
|
||||
onLogEntry(cb: DeviceLogListener): () => void;
|
||||
@@ -79,7 +80,7 @@ export class SandyDevicePluginInstance extends BasePluginInstance {
|
||||
}
|
||||
|
||||
/** client that is bound to this instance */
|
||||
client: DevicePluginClient;
|
||||
readonly client: DevicePluginClient;
|
||||
|
||||
constructor(
|
||||
flipperLib: FlipperLib,
|
||||
|
||||
@@ -12,6 +12,7 @@ import {BasePluginInstance, BasePluginClient} from './PluginBase';
|
||||
import {FlipperLib} from './FlipperLib';
|
||||
import {RealFlipperDevice} from './DevicePlugin';
|
||||
import {batched} from '../state/batch';
|
||||
import {Atom, createState} from '../state/atom';
|
||||
|
||||
type EventsContract = Record<string, any>;
|
||||
type MethodsContract = Record<string, (params: any) => Promise<any>>;
|
||||
@@ -38,6 +39,8 @@ export interface PluginClient<
|
||||
*/
|
||||
readonly appName: string;
|
||||
|
||||
readonly isConnected: boolean;
|
||||
|
||||
/**
|
||||
* the onConnect event is fired whenever the plugin is connected to it's counter part on the device.
|
||||
* For most plugins this event is fired if the user selects the plugin,
|
||||
@@ -101,6 +104,7 @@ export interface PluginClient<
|
||||
*/
|
||||
export interface RealFlipperClient {
|
||||
id: string;
|
||||
connected: Atom<boolean>;
|
||||
query: {
|
||||
app: string;
|
||||
os: string;
|
||||
@@ -134,11 +138,11 @@ export class SandyPluginInstance extends BasePluginInstance {
|
||||
}
|
||||
|
||||
/** base client provided by Flipper */
|
||||
realClient: RealFlipperClient;
|
||||
readonly realClient: RealFlipperClient;
|
||||
/** client that is bound to this instance */
|
||||
client: PluginClient<any, any>;
|
||||
readonly client: PluginClient<any, any>;
|
||||
/** connection alive? */
|
||||
connected = false;
|
||||
readonly connected = createState(false);
|
||||
|
||||
constructor(
|
||||
flipperLib: FlipperLib,
|
||||
@@ -149,6 +153,7 @@ export class SandyPluginInstance extends BasePluginInstance {
|
||||
super(flipperLib, definition, realClient.deviceSync, initialStates);
|
||||
this.realClient = realClient;
|
||||
this.definition = definition;
|
||||
const self = this;
|
||||
this.client = {
|
||||
...this.createBasePluginClient(),
|
||||
get appId() {
|
||||
@@ -157,6 +162,9 @@ export class SandyPluginInstance extends BasePluginInstance {
|
||||
get appName() {
|
||||
return realClient.query.app;
|
||||
},
|
||||
get isConnected() {
|
||||
return self.connected.get();
|
||||
},
|
||||
onConnect: (cb) => {
|
||||
this.events.on('connect', batched(cb));
|
||||
},
|
||||
@@ -212,7 +220,10 @@ export class SandyPluginInstance extends BasePluginInstance {
|
||||
activate() {
|
||||
super.activate();
|
||||
const pluginId = this.definition.id;
|
||||
if (!this.connected && !this.realClient.isBackgroundPlugin(pluginId)) {
|
||||
if (
|
||||
!this.connected.get() &&
|
||||
!this.realClient.isBackgroundPlugin(pluginId)
|
||||
) {
|
||||
this.realClient.initPlugin(pluginId); // will call connect() if needed
|
||||
}
|
||||
}
|
||||
@@ -221,29 +232,29 @@ export class SandyPluginInstance extends BasePluginInstance {
|
||||
deactivate() {
|
||||
super.deactivate();
|
||||
const pluginId = this.definition.id;
|
||||
if (this.connected && !this.realClient.isBackgroundPlugin(pluginId)) {
|
||||
if (this.connected.get() && !this.realClient.isBackgroundPlugin(pluginId)) {
|
||||
this.realClient.deinitPlugin(pluginId);
|
||||
}
|
||||
}
|
||||
|
||||
connect() {
|
||||
this.assertNotDestroyed();
|
||||
if (!this.connected) {
|
||||
this.connected = true;
|
||||
if (!this.connected.get()) {
|
||||
this.connected.set(true);
|
||||
this.events.emit('connect');
|
||||
}
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
this.assertNotDestroyed();
|
||||
if (this.connected) {
|
||||
this.connected = false;
|
||||
if (this.connected.get()) {
|
||||
this.connected.set(false);
|
||||
this.events.emit('disconnect');
|
||||
}
|
||||
}
|
||||
|
||||
destroy() {
|
||||
if (this.connected) {
|
||||
if (this.connected.get()) {
|
||||
this.realClient.deinitPlugin(this.definition.id);
|
||||
}
|
||||
super.destroy();
|
||||
@@ -265,7 +276,7 @@ export class SandyPluginInstance extends BasePluginInstance {
|
||||
|
||||
private assertConnected() {
|
||||
this.assertNotDestroyed();
|
||||
if (!this.connected) {
|
||||
if (!this.connected.get()) {
|
||||
throw new Error('Plugin is not connected');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,23 +90,23 @@ export function getCurrentPluginInstance(): typeof currentPluginInstance {
|
||||
|
||||
export abstract class BasePluginInstance {
|
||||
/** generally available Flipper APIs */
|
||||
flipperLib: FlipperLib;
|
||||
readonly flipperLib: FlipperLib;
|
||||
/** the original plugin definition */
|
||||
definition: SandyPluginDefinition;
|
||||
/** the plugin instance api as used inside components and such */
|
||||
instanceApi: any;
|
||||
/** the device owning this plugin */
|
||||
device: Device;
|
||||
readonly device: Device;
|
||||
|
||||
activated = false;
|
||||
destroyed = false;
|
||||
events = new EventEmitter();
|
||||
readonly events = new EventEmitter();
|
||||
|
||||
// temporarily field that is used during deserialization
|
||||
initialStates?: Record<string, any>;
|
||||
|
||||
// all the atoms that should be serialized when making an export / import
|
||||
rootStates: Record<string, Atom<any>> = {};
|
||||
readonly rootStates: Record<string, Atom<any>> = {};
|
||||
// last seen deeplink
|
||||
lastDeeplink?: any;
|
||||
// export handler
|
||||
@@ -135,6 +135,10 @@ export abstract class BasePluginInstance {
|
||||
get isArchived() {
|
||||
return realDevice.isArchived;
|
||||
},
|
||||
get isConnected() {
|
||||
// for now same as isArchived, in the future we might distinguish between archived/imported and disconnected/offline devices
|
||||
return !realDevice.isArchived;
|
||||
},
|
||||
deviceType: realDevice.deviceType,
|
||||
|
||||
onLogEntry(cb) {
|
||||
|
||||
Reference in New Issue
Block a user