Sfoglia il codice sorgente

Report when a non-SDK app closes

puter.ui.launchApp() returns a Promise that needs to resolve whether the
app uses the Puter SDK or not. Non-SDK apps are tricky because they
don't send a READY message on startup, and we don't know in advance
whether an app will use the SDK or not.

This is a workaround to ensure that launchApp() always resolves. When an
app is closed, if it wasn't using the SDK, we send an artificial
notification that it launched, followed by an extra notification that
it has closed (because the original close notification was sent before
this point). This means any users of launchApp() can await it, and get
an AppConnection, and listen to the close event. They can't otherwise
interact with a non-SDK app because it will have closed already, but we
can improve this in the future without breaking the API.
Sam Atkins 1 anno fa
parent
commit
2890f19bfd
2 ha cambiato i file con 37 aggiunte e 22 eliminazioni
  1. 1 21
      src/UI/UIWindow.js
  2. 36 1
      src/helpers.js

+ 1 - 21
src/UI/UIWindow.js

@@ -2853,27 +2853,7 @@ $.fn.close = async function(options) {
             $(`.window[data-parent_uuid="${window_uuid}"]`).close();
             $(`.window[data-parent_uuid="${window_uuid}"]`).close();
 
 
             // notify other apps that we're closing
             // notify other apps that we're closing
-            if (app_uses_sdk) {
-                // notify parent app, if we have one, that we're closing
-                const parent_id = this.dataset['parent_instance_id'];
-                const parent = $(`.window[data-element_uuid="${parent_id}"] .window-app-iframe`).get(0);
-                if (parent) {
-                    parent.contentWindow.postMessage({
-                        msg: 'appClosed',
-                        appInstanceID: window_uuid,
-                    }, '*');
-                }
-
-                // notify child apps, if we have them, that we're closing
-                const children = $(`.window[data-parent_instance_id="${window_uuid}"] .window-app-iframe`);
-                children.each((_, child) => {
-                    child.contentWindow.postMessage({
-                        msg: 'appClosed',
-                        appInstanceID: window_uuid,
-                    }, '*');
-                });
-                // TODO: Once other AppConnections exist, those will need notifying too.
-            }
+            window.report_app_closed(window_uuid);
 
 
             // remove backdrop
             // remove backdrop
             $(this).closest('.window-backdrop').remove();
             $(this).closest('.window-backdrop').remove();

+ 36 - 1
src/helpers.js

@@ -1899,6 +1899,15 @@ window.launch_app = async (options)=>{
         $(el).on('remove', () => {
         $(el).on('remove', () => {
             const svc_process = globalThis.services.get('process');
             const svc_process = globalThis.services.get('process');
             svc_process.unregister(process.uuid);
             svc_process.unregister(process.uuid);
+
+            // If it's a non-sdk app, report that it launched and closed.
+            // FIXME: This is awkward. Really, we want some way of knowing when it's launched and reporting that immediately instead.
+            const $app_iframe = $(el).find('.window-app-iframe');
+            if ($app_iframe.attr('data-appUsesSdk') !== 'true') {
+                window.report_app_launched(process.uuid, { uses_sdk: false });
+                // We also have to report an extra close event because the real one was sent already
+                window.report_app_closed(process.uuid);
+            }
         });
         });
 
 
         process.references.el_win = el;
         process.references.el_win = el;
@@ -3538,4 +3547,30 @@ window.report_app_launched = (instance_id, { uses_sdk = true }) => {
         }, '*');
         }, '*');
         delete window.child_launch_callbacks[instance_id];
         delete window.child_launch_callbacks[instance_id];
     }
     }
-}
+};
+
+// Run any callbacks to say that the app has closed
+window.report_app_closed = (instance_id) => {
+    const el_window = window_for_app_instance(instance_id);
+
+    // notify parent app, if we have one, that we're closing
+    const parent_id = el_window.dataset['parent_instance_id'];
+    const parent = $(`.window[data-element_uuid="${parent_id}"] .window-app-iframe`).get(0);
+    if (parent) {
+        parent.contentWindow.postMessage({
+            msg: 'appClosed',
+            appInstanceID: instance_id,
+        }, '*');
+    }
+
+    // notify child apps, if we have them, that we're closing
+    const children = $(`.window[data-parent_instance_id="${instance_id}"] .window-app-iframe`);
+    children.each((_, child) => {
+        child.contentWindow.postMessage({
+            msg: 'appClosed',
+            appInstanceID: instance_id,
+        }, '*');
+    });
+
+    // TODO: Once other AppConnections exist, those will need notifying too.
+};