Add keyboard support to Sandy plugin wrapper

Summary: Per title / see rest of the stack

Reviewed By: passy

Differential Revision: D29196711

fbshipit-source-id: 63ea52a07b61a11c1ad4013985c5b005045dcf0a
This commit is contained in:
Michel Weststrate
2021-06-21 08:35:52 -07:00
committed by Facebook GitHub Bot
parent c1860ec19c
commit e40faaef3f
2 changed files with 36 additions and 34 deletions

View File

@@ -90,22 +90,6 @@ export function setupMenuBar(
// create actual menu instance
const applicationMenu = electron.remote.Menu.buildFromTemplate(template);
// add menu items to map, so we can modify them easily later
registeredActions.forEach((keyboardAction) => {
if (keyboardAction != null) {
const {topLevelMenu, label, action} = keyboardAction;
const menu = applicationMenu.items.find(
(menuItem) => menuItem.label === topLevelMenu,
);
if (menu && menu.submenu) {
const menuItem = menu.submenu.items.find(
(menuItem) => menuItem.label === label,
);
menuItem && menuItems.set(action, menuItem);
}
}
});
// update menubar
electron.remote.Menu.setApplicationMenu(applicationMenu);
}
@@ -209,6 +193,8 @@ export function addSandyPluginEntries(entries: NormalizedMenuEntry[]) {
parent.submenu!.append(item);
menuItems.set(entry.action!, item);
changedItems = true;
} else {
console.warn('Invalid top level menu: ' + entry.topLevelMenu);
}
}
}

View File

@@ -17,7 +17,7 @@ import {
PluginClient,
DevicePluginClient,
} from 'flipper-plugin';
import {useEffect, useRef} from 'react';
import {useEffect} from 'react';
import {
BaseAction,
FlipperDevicePlugin,
@@ -32,24 +32,10 @@ export type SandyPluginModule = ConstructorParameters<
>[1];
// Wrapped features
// keyboardActions
// defaultPersistedState
// persistedStateReducer
// exportPersistedState
// getActiveNotifications
// reducers?
// onKeyboardAction
// call _init (not .init) in onactivate / deactivate
// serializePersistedState
// static deserializePersistedState: (
// call _teardown
// dispatchAction
// Device:
// .device property
// Client
// this.client
export function createSandyPluginWrapper<S, A extends BaseAction, P>(
Plugin: typeof FlipperPlugin | typeof FlipperDevicePlugin,
@@ -63,6 +49,7 @@ export function createSandyPluginWrapper<S, A extends BaseAction, P>(
function plugin(client: PluginClient | DevicePluginClient) {
const appClient = isDevicePlugin ? undefined : (client as PluginClient);
const instanceRef = React.createRef<FlipperPlugin<S, A, P> | null>();
const persistedState = createState<P>(Plugin.defaultPersistedState, {
persist: 'persistedState',
@@ -81,7 +68,37 @@ export function createSandyPluginWrapper<S, A extends BaseAction, P>(
}
});
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, topLevelMenu} = def;
return {
label,
accelerator,
topLevelMenu,
handler() {
executeKeyboardAction(action);
},
};
}
}),
);
}
return {
instanceRef,
device: client.device.realDevice,
persistedState,
deeplink,
@@ -104,7 +121,6 @@ export function createSandyPluginWrapper<S, A extends BaseAction, P>(
function Component() {
const instance = usePlugin(plugin);
const logger = useLogger();
const pluginInstanceRef = useRef<FlipperPlugin<S, A, P>>(null);
const persistedState = useValue(instance.persistedState);
const deepLinkPayload = useValue(instance.deeplink);
const dispatch = useDispatch();
@@ -122,7 +138,7 @@ export function createSandyPluginWrapper<S, A extends BaseAction, P>(
const settingsState = useStore((state) => state.settingsState);
useEffect(function triggerInitAndTeardown() {
const ref = pluginInstanceRef.current!;
const ref = instance.instanceRef.current!;
ref._init();
return () => {
ref._teardown();
@@ -143,7 +159,7 @@ export function createSandyPluginWrapper<S, A extends BaseAction, P>(
dispatch(setStaticView(payload));
},
// @ts-ignore ref is not on Props
ref: pluginInstanceRef as any,
ref: instance.instanceRef,
};
return React.createElement(Plugin, props);