Question
When an app raises an Intent, I want running app instances to be considered as Intent handlers only if they are in the currently selected Workspace. The goal is to avoid an Intent being handled by an app instance in a Workspace that isn’t currently in use.
Solution
Use a Plugin in the Main app to intercept the "raise" operation of the "intents" domain.
In the interception handler:
- Use the io.Connect APIs (e.g.,
io.workspacesand/orio.appManager) to compile the list of instances or apps that should be considered as possible handlers. - Set this list as the
handlersproperty of theintentRequestin the intercepted control message. - Forward the
"raise"command to the platform withplatform.system.sendControl(), settingskipInterceptiontotrueto avoid an infinite loop. - Return the result of
sendControl().
Interceptor Example: Filter the Handlers by the Selected Workspace
const raiseIntentInterceptionRequest: IOConnectBrowserPlatform.Plugins.InterceptorRegistrationRequest = {
// @todo: type controlMessage as https://docs.interop.io/browser/capabilities/plugins/domains-operations/index.html#intents-raise
async callInterceptor(controlMessage) {
const activeWorkspace = await io.workspaces?.getWorkspace((workspace) => !!workspace.isSelected)
const workspaceWindows = activeWorkspace?.getAllWindows()
const workspaceWindowIds = new Set(workspaceWindows?.map((workspaceWindow) => workspaceWindow.id))
const intentRequest: IOConnectBrowser.Intents.IntentRequest = controlMessage.data.intentRequest;
const filterFn = (handler: IOConnectBrowser.Intents.IntentHandler) => handler.type === "app" || workspaceWindowIds.has(handler.instanceId);
if (intentRequest.handlers?.length) {
// use the handlers from the intent request to filter the ones from the current wsp
controlMessage.data.intentRequest.handlers = intentRequest.handlers?.filter(filterFn);
return await platform.system.sendControl({ ...controlMessage, settings: { skipInterception: true } });
}
// gather all intent handlers for the current intent request and then filter them
const possibleHandlers = (await io.intents.find(intentRequest.intent)).map((intent) => intent.handlers).flat();
controlMessage.data.intentRequest.handlers = possibleHandlers?.filter(filterFn);
return await platform.system.sendControl({ ...controlMessage, settings: { skipInterception: true } });
},
interceptions: [
{
domain: 'intents',
operation: 'raise',
},
],
}