Let AppConnection know if its target app uses the Puter SDK

Apps are not required to use the Puter SDK. If they don't, then we can
still launch them, close them, and listen to their close event, but are
unable to send messages to them.
This commit is contained in:
Sam Atkins 2024-04-17 11:14:33 +01:00
parent dfdda4f3b9
commit 0aa5543397
3 changed files with 34 additions and 14 deletions

View File

@ -14,7 +14,11 @@ class AppConnection extends EventListener {
// Whether the target app is open
#isOpen;
constructor(messageTarget, appInstanceID, targetAppInstanceID) {
// Whether the target app uses the Puter SDK, and so accepts messages
// (Closing and close events will still function.)
#usesSDK;
constructor(messageTarget, appInstanceID, targetAppInstanceID, usesSDK) {
super([
'message', // The target sent us something with postMessage()
'close', // The target app was closed
@ -23,6 +27,7 @@ class AppConnection extends EventListener {
this.appInstanceID = appInstanceID;
this.targetAppInstanceID = targetAppInstanceID;
this.#isOpen = true;
this.#usesSDK = usesSDK;
// TODO: Set this.#puterOrigin to the puter origin
@ -54,12 +59,21 @@ class AppConnection extends EventListener {
});
}
// Does the target app use the Puter SDK? If not, certain features will be unavailable.
get usesSDK() { return this.#usesSDK; }
// Send a message to the target app. Requires the target to use the Puter SDK.
postMessage(message) {
if (!this.#isOpen) {
console.warn('Trying to post message on a closed AppConnection');
return;
}
if (!this.#usesSDK) {
console.warn('Trying to post message to a non-SDK app');
return;
}
this.messageTarget.postMessage({
msg: 'messageToApp',
appInstanceID: this.appInstanceID,
@ -155,7 +169,7 @@ class UI extends EventListener {
}
if (this.parentInstanceID) {
this.#parentAppConnection = new AppConnection(this.messageTarget, this.appInstanceID, this.parentInstanceID);
this.#parentAppConnection = new AppConnection(this.messageTarget, this.appInstanceID, this.parentInstanceID, true);
}
// Tell the host environment that this app is using the Puter SDK and is ready to receive messages,
@ -374,7 +388,7 @@ class UI extends EventListener {
}
else if (e.data.msg === 'childAppLaunched') {
// execute callback with a new AppConnection to the child
const connection = new AppConnection(this.messageTarget, this.appInstanceID, e.data.child_instance_id);
const connection = new AppConnection(this.messageTarget, this.appInstanceID, e.data.child_instance_id, e.data.uses_sdk);
this.#callbackFunctions[e.data.original_msg_id](connection);
}
else{

View File

@ -90,17 +90,7 @@ window.addEventListener('message', async (event) => {
$(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];
}
window.report_app_launched(event.data.appInstanceID, { uses_sdk: true });
// Send any saved broadcasts to the new app
globalThis.services.get('broadcast').sendSavedBroadcastsTo(event.data.appInstanceID);

View File

@ -3523,3 +3523,19 @@ window.window_for_app_instance = (instance_id) => {
window.iframe_for_app_instance = (instance_id) => {
return $(window_for_app_instance(instance_id)).find('.window-app-iframe').get(0);
};
// Run any callbacks to say that the app has launched
window.report_app_launched = (instance_id, { uses_sdk = true }) => {
const child_launch_callback = window.child_launch_callbacks[instance_id];
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: instance_id,
uses_sdk: uses_sdk,
}, '*');
delete window.child_launch_callbacks[instance_id];
}
}