function legacyPluginWrapper()

in desktop/flipper-ui-core/src/utils/createSandyPluginWrapper.tsx [41:174]


  function legacyPluginWrapper(client: PluginClient | DevicePluginClient) {
    const store = getStore();
    const appClient = isDevicePlugin
      ? undefined
      : (client as PluginClient<any, any>);

    const instanceRef = React.createRef<FlipperPlugin<S, A, P> | null>();
    const persistedState = createState<P>(Plugin.defaultPersistedState);
    const deeplink = createState<unknown>();

    client.onDeepLink((link) => {
      deeplink.set(link);
    });

    appClient?.onUnhandledMessage((event, params) => {
      if (Plugin.persistedStateReducer) {
        persistedState.set(
          Plugin.persistedStateReducer(persistedState.get(), event, params),
        );
      }
    });

    if (
      Plugin.persistedStateReducer ||
      Plugin.exportPersistedState ||
      Plugin.defaultPersistedState
    ) {
      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);
      }

      client.addMenuEntry(
        ...Plugin.keyboardActions.map((def) => {
          if (typeof def === 'string') {
            return {
              action: def,
              handler() {
                executeKeyboardAction(def);
              },
            };
          } else {
            const {action, label, accelerator} = def;
            return {
              label,
              accelerator,
              handler() {
                executeKeyboardAction(action);
              },
            };
          }
        }),
      );
    }

    if (Plugin.getActiveNotifications && !isDevicePlugin) {
      const unsub = persistedState.subscribe((state) => {
        try {
          const notifications = Plugin.getActiveNotifications!(state);
          store.dispatch(
            setActiveNotifications({
              notifications,
              client: appClient!.appId,
              pluginId: Plugin.id,
            }),
          );
        } catch (e) {
          console.error(
            'Failed to compute notifications for plugin ' + Plugin.id,
            e,
          );
        }
      });
      client.onDestroy(unsub);
    }

    return {
      instanceRef,
      device: client.device,
      persistedState,
      deeplink,
      selectPlugin: client.selectPlugin,
      setPersistedState(state: Partial<P>) {
        persistedState.set({...persistedState.get(), ...state});
      },
      get appId() {
        return appClient?.appId;
      },
      get appName() {
        return appClient?.appName ?? null;
      },
      get isArchived() {
        return client.device.isArchived;
      },
      setStaticView(payload: StaticView) {
        store.dispatch(setStaticView(payload));
      },
    };
  }