# Core Integration UI Patterns

## Core Integration UI Patterns

When using **CoreSetup**, the Arcware WebSDK runs in a **headless mode**. This means the SDK does not provide any UI components such as:

* control buttons
* overlays
* status indicators
* queue screens
* AFK warnings

All UI must be implemented by the application.

This page provides **reference patterns** for the most important UI components that are typically implemented when building a Core integration.

The three areas that most Core integrations need to handle are:

1. **Stream control UI**
2. **Queue management UI**
3. **AFK handling UI**

These are the most essential interaction points when building a fully custom interface around the WebSDK.

***

## Base Core Setup Example

Before building UI controls, initialize the SDK.

```typescript
import { CoreSetup } from "@arcware-cloud/pixelstreaming-websdk/core";

const { PixelStreaming } = CoreSetup(
  {
    shareId: "<your-share-id>"
  },
  {
    initialSettings: {
      AutoConnect: true,
      AutoPlayVideo: true,
      StartVideoMuted: true
    }
  }
);

document
  .getElementById("video-container")
  .appendChild(PixelStreaming.rootElement);
```

***

## 1. Stream Control UI

The default UI integration normally provides buttons for:

* fullscreen
* audio toggle
* microphone toggle
* reconnect
* Unreal interaction buttons

When using CoreSetup, these must be implemented manually.

***

### Example Control Panel

Example HTML:

```html
<div id="controls">
  <button id="btn-fullscreen">Fullscreen</button>
  <button id="btn-audio">Toggle Audio</button>
  <button id="btn-mic">Toggle Mic</button>
  <button id="btn-reconnect">Reconnect</button>
</div>
```

Example implementation:

```typescript
let audioEnabled = true;
let micEnabled = false;

document
  .getElementById("btn-fullscreen")
  .addEventListener("click", () => {
    PixelStreaming.rootElement.requestFullscreen();
  });

document
  .getElementById("btn-audio")
  .addEventListener("click", () => {
    audioEnabled = !audioEnabled;
    PixelStreaming.setAudioEnabled(audioEnabled);
  });

document
  .getElementById("btn-mic")
  .addEventListener("click", () => {
    micEnabled = !micEnabled;
    PixelStreaming.toggleMic(micEnabled, false);
  });

document
  .getElementById("btn-reconnect")
  .addEventListener("click", () => {
    PixelStreaming.reconnect();
  });
```

***

### Sending Commands to Unreal Engine

Most custom UI interactions send commands to Unreal Engine.

Example:

```typescript
document
  .getElementById("btn-action")
  .addEventListener("click", () => {
    PixelStreaming.emitUIInteraction({
      action: "OpenMenu"
    });
  });
```

Receiving responses:

```typescript
PixelStreaming.applicationResponseHandler = (response) => {
  console.log("Unreal response:", response);
};
```

***

## 2. Queue Management UI

If all streaming instances are currently occupied, the user may enter the **Arcware queue**.

Without the default UI integration, Core applications must implement queue UI themselves.

***

### Example Queue Overlay

HTML:

```html
<div id="queue-overlay" style="display:none">
  <h2>Waiting for available stream</h2>
  <p id="queue-position"></p>
  <p id="queue-waited"></p>
</div>
```

***

### Handling Queue Updates

```typescript
PixelStreaming.queueHandler.add((message) => {
  const queue = message.queue;

  const overlay = document.getElementById("queue-overlay");

  overlay.style.display = "block";

  const index = queue.index ?? 0;
  const queueLength = queue.queueLength ?? 0;

  document.getElementById("queue-position").innerText =
    `Position in queue: ${index + 1} / ${queueLength}`;

  if (queue.waited !== undefined) {
    document.getElementById("queue-waited").innerText =
      `Already waited: ${queue.waited} ${queue.valueType}`;
  }
});
```

***

### Hiding Queue Overlay When Stream Starts

```typescript
PixelStreaming.videoInitializedHandler.add(() => {
  document.getElementById("queue-overlay").style.display = "none";
});
```

This ensures the queue UI disappears when the stream becomes available.

***

## 3. AFK Handling UI

Arcware streams may terminate sessions when users are inactive.

The backend detects inactivity and emits AFK events through Pixel Streaming.

Core integrations should react to these events to inform users and give them a chance to stay connected.

***

### Example AFK Overlay

HTML:

```html
<div id="afk-overlay" style="display:none">
  <h2>You are inactive</h2>
  <p id="afk-countdown"></p>
</div>
```

***

### AFK Warning Activation

```typescript
PixelStreaming.addEventListener("afkWarningActivate", () => {
  document.getElementById("afk-overlay").style.display = "block";
});
```

***

### AFK Countdown Updates

```typescript
PixelStreaming.addEventListener("afkWarningUpdate", (event) => {
  document.getElementById("afk-countdown").innerText =
    `Disconnecting in ${event.remainingTime}`;
});
```

***

### AFK Warning Cancelled

```typescript
PixelStreaming.addEventListener("afkWarningDeactivate", () => {
  document.getElementById("afk-overlay").style.display = "none";
});
```

***

### AFK Timeout

```typescript
PixelStreaming.addEventListener("afkTimedOut", () => {
  document.getElementById("afk-overlay").innerText =
    "Session ended due to inactivity.";
});
```

***

## Optional: File Transfer Handling

Unreal Engine can send files to the browser.

Example use cases:

* screenshots
* exported assets
* generated reports

***

### Automatic Download

```typescript
PixelStreaming.fileTransferHandler.add(() => {
  PixelStreaming.fileDownload();
});
```

***

### Fully Custom File Handling

```typescript
PixelStreaming.fileTransferHandler.add(() => {
  const file = PixelStreaming.getIncomingFile();

  const blob = new Blob(file.data, {
    type: file.mimetype
  });

  console.log("Received file:", blob);
});
```

This allows applications to:

* preview files
* upload files to a server
* process them programmatically

***

## Typical Core UI Structure

Most Core integrations implement at least the following components:

| Component        | Purpose                               |
| ---------------- | ------------------------------------- |
| Stream container | Rendering the video stream            |
| Control panel    | Stream controls and commands          |
| Queue overlay    | Inform user when waiting for capacity |
| AFK overlay      | Handle inactivity warnings            |
| File handling    | Optional asset downloads              |

***

## Minimal Example Layout

```html
<div id="video-container"></div>

<div id="controls"></div>

<div id="queue-overlay"></div>

<div id="afk-overlay"></div>
```

This structure gives applications full control over how the streaming interface behaves.

***

## Summary

When using **CoreSetup**, developers must implement the UI components that the UI integration normally provides automatically.

The most important UI areas to handle are:

* **stream controls**
* **queue handling**
* **AFK handling**

Together with `emitUIInteraction()` and `applicationResponseHandler`, these components form the core interaction model for most headless integrations.
