From 806dd63f680d5f02fdb6c8bcf09b1f1101ca704e Mon Sep 17 00:00:00 2001 From: Michel Weststrate Date: Mon, 21 Jun 2021 08:35:52 -0700 Subject: [PATCH] Add wrapper support for import / export states Summary: Make sure custom export handlers of classic plugins wrapped in Sandy are respected Reviewed By: passy Differential Revision: D29233604 fbshipit-source-id: 7bab33af3422e0b59697438577906ce8580a28ad --- .../src/utils/createSandyPluginWrapper.tsx | 52 ++++++++++++++++--- desktop/app/src/utils/exportData.tsx | 1 + desktop/plugins/public/layout/index.tsx | 4 +- 3 files changed, 48 insertions(+), 9 deletions(-) diff --git a/desktop/app/src/utils/createSandyPluginWrapper.tsx b/desktop/app/src/utils/createSandyPluginWrapper.tsx index 0c904bd5c..e9e4d16b0 100644 --- a/desktop/app/src/utils/createSandyPluginWrapper.tsx +++ b/desktop/app/src/utils/createSandyPluginWrapper.tsx @@ -32,10 +32,7 @@ export type SandyPluginModule = ConstructorParameters< >[1]; // Wrapped features -// exportPersistedState // getActiveNotifications -// serializePersistedState -// static deserializePersistedState: ( export function createSandyPluginWrapper( Plugin: typeof FlipperPlugin | typeof FlipperDevicePlugin, @@ -48,12 +45,12 @@ export function createSandyPluginWrapper( ); function plugin(client: PluginClient | DevicePluginClient) { - const appClient = isDevicePlugin ? undefined : (client as PluginClient); + const appClient = isDevicePlugin + ? undefined + : (client as PluginClient); const instanceRef = React.createRef | null>(); - const persistedState = createState

(Plugin.defaultPersistedState, { - persist: 'persistedState', - }); + const persistedState = createState

(Plugin.defaultPersistedState); const deeplink = createState(); client.onDeepLink((link) => { @@ -68,6 +65,47 @@ export function createSandyPluginWrapper( } }); + if ( + Plugin.persistedStateReducer || + Plugin.exportPersistedState || + Plugin.defaultPersistedState || + Plugin.serializePersistedState + ) { + client.onExport(async (idler, onStatusMessage) => { + const state = Plugin.exportPersistedState + ? await Plugin.exportPersistedState( + isDevicePlugin + ? undefined + : (method: string, params: any) => + appClient!.send(method, params), + persistedState.get(), + undefined, // passing an undefined Store is safe, as no plugin actually uses this param + idler, + onStatusMessage, + isDevicePlugin + ? undefined + : (method: string) => appClient!.supportsMethod(method), + ) + : persistedState.get(); + // respect custom serialization + return Plugin.serializePersistedState + ? await Plugin.serializePersistedState( + state, + onStatusMessage, + idler, + Plugin.id, + ) + : state; + }); + + client.onImport((data) => { + if (Plugin.deserializePersistedState) { + data = Plugin.deserializePersistedState(data); + } + persistedState.set(data); + }); + } + if (Plugin.keyboardActions) { function executeKeyboardAction(action: string) { instanceRef?.current?.onKeyboardAction?.(action); diff --git a/desktop/app/src/utils/exportData.tsx b/desktop/app/src/utils/exportData.tsx index 02c3062b5..abc5a3c43 100644 --- a/desktop/app/src/utils/exportData.tsx +++ b/desktop/app/src/utils/exportData.tsx @@ -264,6 +264,7 @@ async function exportSandyPluginStates( if (!res[client.id]) { res[client.id] = {}; } + // makeObjectSerializable is slow but very convenient by default. If people want to speed things up res[client.id][pluginId] = await makeObjectSerializable( await client.sandyPluginStates .get(pluginId)! diff --git a/desktop/plugins/public/layout/index.tsx b/desktop/plugins/public/layout/index.tsx index 22f8d1872..7f429d921 100644 --- a/desktop/plugins/public/layout/index.tsx +++ b/desktop/plugins/public/layout/index.tsx @@ -84,12 +84,12 @@ export default class LayoutPlugin extends FlipperPlugin< | undefined | ((method: ClientMethodCalls, params?: any) => Promise), persistedState: PersistedState | undefined, - store: ReduxState | undefined, + _store: ReduxState | undefined, _idler?: Idler | undefined, statusUpdate?: (msg: string) => void, supportsMethod?: (method: ClientMethodCalls) => Promise, ): Promise => { - if (!store || !callClient) { + if (!callClient) { return persistedState; } statusUpdate && statusUpdate('Fetching Root Node...');