mirror of
https://github.com/HeyPuter/puter
synced 2024-11-15 06:15:47 +00:00
Merge pull request #238 from AtkinsSJ/app-ipc
Implement support for launching child apps, and IPC between a parent and its children
This commit is contained in:
commit
95d33eab94
56
src/IPC.js
56
src/IPC.js
@ -74,10 +74,14 @@ window.addEventListener('message', async (event) => {
|
||||
return;
|
||||
}
|
||||
|
||||
const iframe_for_app_instance = (instanceID) => {
|
||||
return $(`.window[data-element_uuid="${instanceID}"]`).find('.window-app-iframe').get(0)
|
||||
};
|
||||
|
||||
const $el_parent_window = $(`.window[data-element_uuid="${event.data.appInstanceID}"]`);
|
||||
const parent_window_id = $el_parent_window.attr('data-id');
|
||||
const $el_parent_disable_mask = $el_parent_window.find('.window-disable-mask');
|
||||
const target_iframe = $(`.window[data-element_uuid="${event.data.appInstanceID}"]`).find('.window-app-iframe').get(0);
|
||||
const target_iframe = iframe_for_app_instance(event.data.appInstanceID);
|
||||
const msg_id = event.data.uuid;
|
||||
const app_name = $(target_iframe).attr('data-app');
|
||||
const app_uuid = $el_parent_window.attr('data-app_uuid');
|
||||
@ -88,6 +92,19 @@ window.addEventListener('message', async (event) => {
|
||||
//-------------------------------------------------
|
||||
if(event.data.msg === 'READY'){
|
||||
$(target_iframe).attr('data-appUsesSDK', 'true');
|
||||
|
||||
// If we were waiting to launch this as a child app, report to the parent that it succeeded.
|
||||
const child_launch_callback = window.child_launch_callbacks[event.data.appInstanceID];
|
||||
if (child_launch_callback) {
|
||||
const parent_iframe = iframe_for_app_instance(child_launch_callback.parent_instance_id);
|
||||
// send confirmation to requester window
|
||||
parent_iframe.contentWindow.postMessage({
|
||||
msg: 'childAppLaunched',
|
||||
original_msg_id: child_launch_callback.launch_msg_id,
|
||||
child_instance_id: event.data.appInstanceID,
|
||||
}, '*');
|
||||
delete window.child_launch_callbacks[event.data.appInstanceID];
|
||||
}
|
||||
}
|
||||
//-------------------------------------------------
|
||||
// windowFocused
|
||||
@ -496,16 +513,20 @@ window.addEventListener('message', async (event) => {
|
||||
// launchApp
|
||||
//--------------------------------------------------------
|
||||
else if(event.data.msg === 'launchApp'){
|
||||
// launch app
|
||||
// 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 = 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,
|
||||
});
|
||||
|
||||
// send confirmation to requester window
|
||||
target_iframe.contentWindow.postMessage({
|
||||
original_msg_id: msg_id,
|
||||
}, '*');
|
||||
}
|
||||
//--------------------------------------------------------
|
||||
// readAppDataFile
|
||||
@ -1054,6 +1075,27 @@ window.addEventListener('message', async (event) => {
|
||||
}
|
||||
}
|
||||
}
|
||||
//--------------------------------------------------------
|
||||
// messageToApp
|
||||
//--------------------------------------------------------
|
||||
else if (event.data.msg === 'messageToApp') {
|
||||
const { appInstanceID, targetAppInstanceID, targetAppOrigin, contents } = event.data;
|
||||
// TODO: Determine if we should allow the message
|
||||
// TODO: Track message traffic between apps
|
||||
|
||||
// pass on the message
|
||||
const target_iframe = iframe_for_app_instance(targetAppInstanceID);
|
||||
if (!target_iframe) {
|
||||
console.error('Failed to send message to non-existent app', event);
|
||||
return;
|
||||
}
|
||||
target_iframe.contentWindow.postMessage({
|
||||
msg: 'messageToApp',
|
||||
appInstanceID,
|
||||
targetAppInstanceID,
|
||||
contents,
|
||||
}, targetAppOrigin);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// exit
|
||||
|
@ -130,6 +130,9 @@ window.launch_apps = [];
|
||||
window.launch_apps.recent = []
|
||||
window.launch_apps.recommended = []
|
||||
|
||||
// Map of { child_instance_id -> { parent_instance_id, launch_msg_id } }
|
||||
window.child_launch_callbacks = {};
|
||||
|
||||
// Is puter being loaded inside an iframe?
|
||||
if (window.location !== window.parent.location) {
|
||||
window.is_embedded = true;
|
||||
|
@ -1849,7 +1849,7 @@ window.trigger_download = (paths)=>{
|
||||
* @param {*} options
|
||||
*/
|
||||
window.launch_app = async (options)=>{
|
||||
const uuid = uuidv4();
|
||||
const uuid = options.uuid ?? uuidv4();
|
||||
let icon, title, file_signature;
|
||||
const window_options = options.window_options ?? {};
|
||||
|
||||
@ -1945,6 +1945,11 @@ window.launch_app = async (options)=>{
|
||||
// add app_id to URL
|
||||
iframe_url.searchParams.append('puter.app.id', app_info.uuid);
|
||||
|
||||
// add parent_app_instance_id to URL
|
||||
if (options.parent_instance_id) {
|
||||
iframe_url.searchParams.append('puter.parent_instance_id', options.parent_instance_id);
|
||||
}
|
||||
|
||||
if(file_signature){
|
||||
iframe_url.searchParams.append('puter.item.uid', file_signature.uid);
|
||||
iframe_url.searchParams.append('puter.item.path', options.file_path ? `~/` + options.file_path.split('/').slice(1).join('/') : file_signature.path);
|
||||
|
Loading…
Reference in New Issue
Block a user