Support handling deeplinks in plugins

Summary:
This adds support for handling incoming deeplinks in a Sandy plugin, which can be done by using a `client.onDeepLink(deepLink => { } )` listener

Also generalized deeplinks to not just support strings, but also richer objects, which is beneficial to plugin to plugin linking.

Reviewed By: jknoxville

Differential Revision: D22524749

fbshipit-source-id: 2cbe8d52f6eac91a1c1c8c8494706952920b9181
This commit is contained in:
Michel Weststrate
2020-07-22 04:11:32 -07:00
committed by Facebook GitHub Bot
parent 485b4c9827
commit f0c54667e0
13 changed files with 225 additions and 31 deletions

View File

@@ -46,6 +46,11 @@ export interface FlipperClient<
*/
onDisconnect(cb: () => void): void;
/**
* Triggered when this plugin is opened through a deeplink
*/
onDeepLink(cb: (deepLink: unknown) => void): void;
/**
* Send a message to the connected client
*/
@@ -113,6 +118,8 @@ export class SandyPluginInstance {
initialStates?: Record<string, any>;
// all the atoms that should be serialized when making an export / import
rootStates: Record<string, Atom<any>> = {};
// last seen deeplink
lastDeeplink?: any;
constructor(
realClient: RealFlipperClient,
@@ -143,6 +150,9 @@ export class SandyPluginInstance {
onMessage: (event, callback) => {
this.events.on('event-' + event, callback);
},
onDeepLink: (callback) => {
this.events.on('deeplink', callback);
},
};
currentPluginInstance = this;
this.initialStates = initialStates;
@@ -165,6 +175,7 @@ export class SandyPluginInstance {
// the plugin is deselected in the UI
deactivate() {
this.lastDeeplink = undefined;
if (this.destroyed) {
// this can happen if the plugin is disabled while active in the UI.
// In that case deinit & destroy is already triggered from the STAR_PLUGIN action
@@ -211,6 +222,14 @@ export class SandyPluginInstance {
return '[SandyPluginInstance]';
}
triggerDeepLink(deepLink: unknown) {
this.assertNotDestroyed();
if (deepLink !== this.lastDeeplink) {
this.lastDeeplink = deepLink;
this.events.emit('deeplink', deepLink);
}
}
exportState() {
return Object.fromEntries(
Object.entries(this.rootStates).map(([key, atom]) => [key, atom.get()]),