# Remote Controlled Image Slideshow Display

The **RCWeb Slideshow Display** app (`app/slideshow`) is a **Remote controlled Image Slideshow** for TVs, projectors, monitors, kiosk browsers, and shared screens. It is the big-screen half of the RCWeb slideshow player and is controlled from phones, tablets, or other browsers in the same RCWeb room.

![icon](pwa-512x512.png "Slideshow Display Icon")

## Overview

This app turns the browser into a remote controlled photo and image slideshow. The display shows a QR code for phones to join as controllers, receives images from one or more `slideshow-c` apps, caches those images locally, and then plays them in a continuous loop.

The display is intentionally simple during playback: images fill the screen, while the QR code, fullscreen button, title, status, and diagnostics panels can be shown or hidden from the control app.

## How to use

1. Open `/slideshow/` on the display browser.
2. Scan the QR code with a phone, or manually open `/slideshow-c/?r=<room>` on another browser.
3. Use the control app to add images from the phone or computer.
4. Wait while the display downloads and caches the images. Progress is shown on screen.
5. The slideshow starts automatically after the images are cached.
6. Use the control app to reorder images, remove images, change slide duration, choose transitions, or clear the slideshow.
7. Press **Fullscreen** on the display when the screen is ready.

## Remote Controlled Image Slideshow Features

- Shows a QR code that opens the matching `slideshow-c` controller in the same room.
- Receives local image selections from controller browsers through RCWeb's file proxy.
- Primes the browser's cache with each `/x-file/` image URL and stores playlist metadata in local storage.
- Restores the last slideshow after the display is refreshed, as long as the local cache is still available.
- Verifies cached images before playback and shows a visible error if an image is missing.
- Loops continuously through the image playlist.
- Supports slide duration changes from 2 to 120 seconds.
- Supports **No transition**, **Fade**, and **Ken Burns** transition modes.
- Supports **Fill screen**, **Add border**, and **Stretch** scaling modes.
- Uses JavaScript-calculated image dimensions so portrait images keep their shape on older browsers.
- Can hide or show slideshow information, diagnostics, QR code, and fullscreen controls.
- Includes a service worker and web manifest so the viewer shell can be installed or reopened offline after it has been loaded once.

## Image scaling

**Fill screen** crops the image as needed so the whole display is covered.

**Add border** keeps the full image visible and adds border space only on the unused axis: side borders for tall images, or top and bottom borders for wide images.

**Stretch** forces the image to fill the exact screen shape. This may distort photos, but can be useful for prepared content that already matches the display.

## Cache and offline behavior

The display is the authoritative device for the remote controlled image slideshow after images are cached. It keeps the playlist manifest in local storage and reuses the browser's cached `/x-file/` image responses. When the display reloads, it checks that every image URL can still be loaded before it starts playback.

If the display has already loaded the app shell and cached the slideshow images, it can reopen the last slideshow without the RCWeb server. Offline playback is limited to images that are already cached on that display device. Adding new images, controlling from a phone, and synchronizing with other browsers still require the RCWeb server connection.

Browsers without service worker support can still use the slideshow online, but cannot use the offline app shell.

## Multiple controls

Several `slideshow-c` control browsers can be open in the same room. Controls request the latest state from the display and render the playlist from that state.

If a control browser is refreshed after the display has cached the images, it can recover the playlist order, titles, status, and playback settings from the display. The display can recreate thumbnail previews from the cached image URLs and share those thumbnails back through RCWeb's file proxy.

## How RCWeb makes it possible

RCWeb gives every browser tab a room, app name, and client ID, then connects clients in the same room over WebSocket. The controller sends commands to the `slideshow` display app, and the display publishes state snapshots back to `slideshow-c`.

Large image files are not sent directly through WebSocket messages. The controller exposes each resized image through RCWeb's `/x-file/` proxy, and the display loads those URLs sequentially so the browser can cache the immutable image responses.

## Related app

Use this app with **RCWeb Slideshow Control** (`app/slideshow-c`).
