User Tools

Site Tools


en:outskirts:mages-peaks:detach-windows

This is an old revision of the document!


Goals

As demonstrated in the laelith-adventure project, for the Editor, the goal is to enable a (Svelte) component sitting in a page to be detached into a popup window, that can be moved around independently, and notably make better use of multi-screen setups.
However, communicating with a local Svelte component and communicating with a component in a popup window do not involve the same techniques.
We introduce here the intercoms utility, that helps managing the communication with detachable components. The main design goal here is to have the same way to communicate with the component, be it local or in a detached window.

Attaching/Detaching a View

Properties of the detacheable component

A detachable Svelte component must have a detached svelte property, to become aware of its attached/detached status. It may have callbacks such as the onClose and onDetach shown below if the container in which it is embedded (in non-detached mode) needs to be made aware of its status change to adapt the layout.

  export let detached:boolean;
  
  // onClose and onDetach only active for the non-detached "anchor" instance.
  export let onClose: () => void = () => {};
  export let onDetach: (detached: boolean) => void = (_detached) => {};

A container page for the detached version will pass detached=true, the embedded version will receive detached=false.

Attach/Detach management code within the Component

Within the Svelte component, the following example code manages the operation:

  const intercom = detached
    ? intercoms.newDetachedIntercom("MyViewId")
    : intercoms.newIntercom("MyViewId");
  let fullyDetached = false;
  
  // The Embedded Component requests its container to destroy it.
  const closeButton = () => {
    onClose();
  };
  
  // Closing the detached popup window reattaches the component
  const reattach = () => {
    window.close();
  };

  const detach = () => {
    const ghostId = intercoms.detachMe("MyViewId");
    const detachedWindow = window.open(
      "/?p=detached-page-url",
      "Target",
      "popup,left:0, bottom= 300px, width=500px, height=600px",
    );
    if (detachedWindow) {
      intercoms.declareChild(ghostId, "MyViewId", detachedWindow).then(() => {
        fullyDetached = true;
        onDetach(true);    // Notify the container if needed
      });
    } else {
      intercoms.undetachMe("MyViewId");  // cancel detach
    }
  };
  
  onMount(() => {
    intercom.on(Intercom.RX_MESSAGE,
      (msg: IntercomMessage) => {
        switch (msg.msgType) {
          case "wake-up":
            fullyDetached = false;
            onDetach(false);
            // If needed, re-init code for the reattached component
            break;
        }
      },
      "myview",
    );
    intercom.whenReady().then(() => {
      // If needed, init code for the component
    });
  });
  onDestroy(() => {
    intercoms.destroyIntercom("MyViewId");
  });
  
  </script>

{#if !fullyDetached}
  // Here the Svelte code of the component
{/if}

The const intercom = detached ? newDetachedIntercom… code declares this Component to the Intercoms system.

The const ghostId = intercoms.detachMe(“MyViewId”); line prepares the detachment, that wil “ghost” the embedded component.

Then the const detachedWindow = window.open(…) really creates the detached popup window. The page opened at this URL should embedd our component, with the detached=true property.

The intercoms.declareChild(ghostId, “MyViewId”, detachedWindow).then(() ⇒ { gives the reference of the (child) detached window to the Intercoms system, that will handshake with it. When the detached window is known to be present and operational, the returned Promise returns, allowing to complete the detachment operation.

When the view is mounted, it listens to Intercom messages (with intercom.on(Intercom.RX_MESSAGE) and must handle the wake-up signal – this signal notifies the embedded “ghosted” view that the detached window has closed.

Using the Intercoms to communicate

Readiness signals

Attaching / Detaching views involves a number of non-instantaneous, asynchronous operations.

en/outskirts/mages-peaks/detach-windows.1712680730.txt.gz · Last modified: 2024/10/28 08:00 (external edit)