diff --git a/src/gui/src/IPC.js b/src/gui/src/IPC.js index 356e72e06..b9f136bc0 100644 --- a/src/gui/src/IPC.js +++ b/src/gui/src/IPC.js @@ -32,6 +32,7 @@ import update_mouse_position from './helpers/update_mouse_position.js'; import launch_app from './helpers/launch_app.js'; import item_icon from './helpers/item_icon.js'; +window.ipc_handlers = {}; /** * In Puter, apps are loaded in iframes and communicate with the graphical user interface (GUI), and each other, using the postMessage API. * The following sets up an Inter-Process Messaging System between apps and the GUI that enables communication @@ -88,6 +89,17 @@ window.addEventListener('message', async (event) => { const msg_id = event.data.uuid; const app_name = $(target_iframe).attr('data-app'); const app_uuid = $el_parent_window.attr('data-app_uuid'); + + if ( window.ipc_handlers.hasOwnProperty(event.data.msg) ) { + console.log('got message to new IPC handler', event.data.msg); + const ipc_context = { + appInstanceId: event.data.appInstanceID, + }; + const spec = window.ipc_handlers[event.data.msg]; + await spec.handler(event.data, { msg_id, ipc_context }); + console.log('^ end of that thing'); + return; + } // todo validate all event.data stuff coming from the client (e.g. event.data.message, .msg, ...) //------------------------------------------------- @@ -846,25 +858,6 @@ window.addEventListener('message', async (event) => { window.watchItems[event.data.item_uid].push(event.data.appInstanceID); } //-------------------------------------------------------- - // launchApp - //-------------------------------------------------------- - else if(event.data.msg === 'launchApp'){ - // TODO: Determine if the app is allowed to launch child apps? We may want to limit this to prevent abuse. - // remember app for launch callback later - const child_instance_id = window.uuidv4(); - window.child_launch_callbacks[child_instance_id] = { - parent_instance_id: event.data.appInstanceID, - launch_msg_id: msg_id, - }; - // launch child app - launch_app({ - name: event.data.app_name ?? app_name, - args: event.data.args ?? {}, - parent_instance_id: event.data.appInstanceID, - uuid: child_instance_id, - }); - } - //-------------------------------------------------------- // readAppDataFile //-------------------------------------------------------- else if(event.data.msg === 'readAppDataFile' && event.data.path !== undefined){ diff --git a/src/gui/src/initgui.js b/src/gui/src/initgui.js index b2a3e66be..df1907781 100644 --- a/src/gui/src/initgui.js +++ b/src/gui/src/initgui.js @@ -46,6 +46,8 @@ import update_mouse_position from './helpers/update_mouse_position.js'; import { LaunchOnInitService } from './services/LaunchOnInitService.js'; import item_icon from './helpers/item_icon.js'; import { AntiCSRFService } from './services/AntiCSRFService.js'; +import { IPCService } from './services/IPCService.js'; +import { ExecService } from './services/ExecService.js'; const launch_services = async function (options) { // === Services Data Structures === @@ -75,6 +77,8 @@ const launch_services = async function (options) { globalThis.service_script_api_promise.resolve(service_script_api); // === Builtin Services === + register('ipc', new IPCService()); + register('exec', new ExecService()); register('broadcast', new BroadcastService()); register('theme', new ThemeService()); register('process', new ProcessService()); diff --git a/src/gui/src/services/ExecService.js b/src/gui/src/services/ExecService.js new file mode 100644 index 000000000..62e9f240a --- /dev/null +++ b/src/gui/src/services/ExecService.js @@ -0,0 +1,26 @@ +import { Service } from "../definitions.js"; +import launch_app from "../helpers/launch_app.js"; + +export class ExecService extends Service { + async _init ({ services }) { + const svc_ipc = services.get('ipc'); + svc_ipc.register_ipc_handler('launchApp', { + handler: this.launchApp.bind(this), + }); + } + + launchApp ({ app_name, args }, { ipc_context, msg_id } = {}) { + const child_instance_id = window.uuidv4(); + window.child_launch_callbacks[child_instance_id] = { + parent_instance_id: event.data.appInstanceID, + launch_msg_id: msg_id, + }; + // launch child app + launch_app({ + name: app_name, + args: args ?? {}, + parent_instance_id: ipc_context?.appInstanceId, + uuid: child_instance_id, + }); + } +} diff --git a/src/gui/src/services/IPCService.js b/src/gui/src/services/IPCService.js new file mode 100644 index 000000000..f2f025c87 --- /dev/null +++ b/src/gui/src/services/IPCService.js @@ -0,0 +1,11 @@ +import { Service } from "../definitions.js"; + +export class IPCService extends Service { + async _init () { + // + } + + register_ipc_handler (name, spec) { + window.ipc_handlers[name] = spec; + } +}