# Wallboard Content Architecture & System Overview

## Content Types & Device Assignment

### Main Content Types (Device-Assignable)
Only **ONE** content assigned per device at a time, plus optional emergency overlay:

1. **Playlist** - Sequential playback of multiple items
2. **Slide** - Single-page content with limited embedding (Version 2.1+)
3. **Content** - Multi-page, full-feature content with full embedding
4. **Emergency Content** - Absolute priority overlay

## License Restrictions & Capabilities

| License | Playlist | Slide | Content | Limitations |
|---------|----------|-------|---------|-------------|
| **Lite** | ✅ | ❌* | ❌ | *Slides exist but skipped during playlist playback on Lite devices. Not available in USA. |
| **Professional** | ✅ | ✅ | ✅ | No PowerBI widget, no sensor events |
| **Premium** | ✅ | ✅ | ✅ | No restrictions |
| **Video Wall** | ✅ | ✅ | ✅ | Premium + multi-monitor support |

**Note:** Lite license devices can only be assigned Playlists. Slides within playlists are automatically skipped during playback.

## Two Embedding Ecosystems (Version 2.1+)

### 1. Slide + Playlist Ecosystem (Primary, Recommended)

**Slide capabilities:**
- Single page only
- **Embedding allowed (2.1+)**: Slide widget (1 slide), Playlist widget, Channel widget
- **NO interactivity**: No sensor events, no complex actions
- Playlist-compatible
- **Recommended approach** for most signage needs

**Playlist capabilities:**
- Contains: Media files, media folders, Slides, Slide folders, nested Playlists
- Cannot contain: Multi-page Content

**Use cases:**
- General digital signage (recommended)
- Sequential playback
- Template-based content
- Multi-location deployments
- Simple content management

### 2. Content Ecosystem (Advanced, Special Cases)

**Content capabilities:**
- Multi-page with navigation
- **Full embedding**: Slides (via Slide widget), Playlists (via Playlist widget), Channels (via Channel widget), nested Content (via Content/Contents widgets), Media widgets
- **Full interactivity**: Sensor events, page actions, complex navigation
- **Cannot be embedded anywhere**: Not in Slides, not in Playlists, only in other Content

**Use cases (advanced users only):**
- Interactive kiosks requiring sensors
- Complex multi-page applications
- Advanced navigation logic
- Specialized interactive experiences

### Architectural Rules

**Slide widget (Version 2.1+):**
- Available in: Slide, Content
- References: 1 slide (selected in widget configuration)

**Playlist widget:**
- Available in: Slide, Content
- References: Multiple playlists (selected in widget configuration)

**Content widget (singular):**
- Available in: Content only
- References: 1 Content item (selected in widget configuration)

**Contents widget (plural):**
- Available in: Content only
- References: Multiple Content items (drag-and-drop sequencing in widget configuration)

**Channel widget:**
- Available in: Slide, Content
- References: Multiple main channels (tag-based filtering or all channels)
- **Sophisticated selection**: "Channels with tags only" toggle determines channel inclusion
- **Sequential playback**: Channels play in order (not simultaneously)
- **Saturation balancing**: Controls relative time/items between selected main channels
- **Dynamic tag management**: Tags can update during playback (IoT, AI, API)

**Critical constraint:** Multi-page Content cannot be added to Playlists or embedded in Slides (policy restriction).

**Note:** ePaper devices do not support **Channels** or **Schedules**. System automatically excludes ePaper devices from "Where to play" selection to prevent misconfiguration.

## Content vs Slide: Architectural Differences

### Slide (Primary, Recommended for Most Use Cases)
- **Single page only**
- **Limited embedding**: Slide widget (1 slide), Playlist widget, Channel widget
- **No interactivity**: No sensor events, no complex actions
- **Playlist-compatible** - works seamlessly in sequential playback
- **Convertible to Content** if advanced features needed later
- **Recommended approach** for standard digital signage

### Content (Advanced, Special Use Cases Only)
- **Multi-page capable**
- **Full embedding**: Slide widget, Playlist widget, Channel widget, Content/Contents widgets, Media widgets
- **Full interactivity**: Sensor events, page actions, complex navigation
- **Cannot be embedded in Slides or Playlists**
- **Conditional conversion to Slide**: Only if single-page, no interactivity, compatible embedding
- **Use only when Slide+Playlist insufficient** for requirements

### Selection Logic

**Use Slide (Primary Recommendation):**
- Single-page requirement
- Playlist compatibility needed
- No interactivity required
- Slide, Playlist, or Channel widget embedding sufficient
- Template reuse intended
- **Most common signage scenarios**

**Use Playlist (Primary Recommendation):**
- Sequential presentation
- Item-level scheduling required
- Collection playback modes needed
- Mixed media types
- Fallback/exclusive modes required
- **Standard multi-item content delivery**

**Use Content (Advanced Users Only):**
- Interactive kiosks requiring sensor integration
- Complex multi-page applications with advanced navigation
- Specialized interactive experiences
- **Only when Slide+Playlist insufficient**

## Playlist System

### Playlist Contents

**Allowed:**
- Media files (images, videos, audio, PDF)
- Media folders
- Slides
- Slide folders
- Nested playlists

**Prohibited:**
- Multi-page Content (policy restriction)

**Open linked resources:** In Playlist editor, **Open playlist** and **Open slide** open the referenced original source for editing, separately from occurrence Quick editing. Use the linked item header or grid preview; Scheduler has a separate open action because its header selects the item. A nested Playlist opens in the same tab, with **Save changes**, **Discard changes**, or **Cancel** when leaving requires confirmation. A Slide opens in an embedded editor; closing it returns to the still-open Playlist and retains pending Playlist changes. Ctrl/Cmd-click (or supported middle-click) opens the target in a new tab without forcing a parent save/discard decision. A child Playlist can show a return chevron with the originating parent's name as its tooltip when that parent is recognized in saved usage, alongside a separate **Leave editor** control. Source targets must resolve, be non-removed and unlocked, and pass source edit/management and editor visibility gates; Playlist edit rights alone do not grant Slide edit rights. **Open folder** browses linked file folders in the Media selector or File Manager modal, depending on editor layout. In Contents details, the **Embedded usage** pencil (**Edit content**) opens an editable parent Playlist.

### Paginated Slides

**Concept:** Datasource-bound Slide used as a playlist collection. One Slide template expands at playback into runtime entries from datasource rows; generated entries are not persisted as duplicated content pages.

**Authoring:** Enable "Data binding with pagination" on a Slide that uses a content-level datasource binding. The template binds to required datasource structure/paths, not one fixed datasource instance. When adding it to a Playlist, choose normal Slide or Paginated Slide.

**Template library pattern:** Wallboard/partner-provided templates can ship the binding structure centrally; customers pull the template and provide or swap in a compatible datasource.

**Playback:** Only the Slide's Default page renders. Each generated entry uses a datasource row group. Without row offsets the group size is 1. Base-dependent widget bindings can set a row offset: 0 = first row, 1 = second row, etc.; highest offset + 1 becomes the rows consumed per generated entry. Incomplete final row groups hide offset-bound widgets without matching rows.

**Controls:** Uses collection-style playlist settings: ordering, play elements, specific count, count collections, item cap, schedule and page targeting, mute, quick edit, static or widget-based duration. Playlist quick-edit datasource override changes the concrete datasource for all generated entries; replacement must keep the template's expected structure.

**Runtime state:** Remember playback position defaults ON and survives playlist/slider component remounts; OFF restarts from first datasource row. If the Slide, datasource, datasource path used for row expansion, or row entries are missing, the item contributes no playback entries. Basic-license devices skip Paginated Slides. Native device clients do not handle this specially; the browser-based playback runtime expands the entries.

### Slide Page Duration

**Content picker:** Each selected Content, Slide, or Playlist can independently use **Dynamic** source duration or a **Static** item duration. New selections default to Dynamic; Static uses a 3-second minimum and 15 seconds when no value exists.

**Playlist page:** **Duration source** = Static or Dynamic. Static uses the page duration; reset restores the Playlist's default duration (12 seconds when no default is set). Dynamic requires **Duration based on widget** and is unavailable without a compatible Video, Audio, Stream, Video Gallery, Image Gallery, Slide, Playlist, or Channel widget. A Slide with a default duration widget is added as Dynamic; otherwise the editor presents Static.

**Runtime:** Dynamic follows the selected widget, including recursive Slide/Playlist content. Missing/unresolvable sources and circular references use the configured Slide duration.

### Playlist Playback Modes

**Default Mode:**
- Normal rotation, shares playlist time

**Exclusive Mode:**
- Suppresses Default/Fallback when active
- Multiple Exclusives play together
- Schedule-dependent

**Fallback Mode:**
- Plays ONLY when no Default/Exclusive active
- Prevents blank screens

**Priority:** Exclusive → Default → Fallback → Blank/"No Content"

### Playlist Page Targeting

- **Where to play:** On a standard Playlist page, open **Settings -> Playlist page settings -> Where to play**. Choose **Dynamic - with tags and folder** or **Dynamic - with quick filter**. ePaper pages use their own settings.
- **Tags and Folders:** New tag selections default to **Any match**; **All match** requires every selected tag. A selected Folder includes its subfolders, multiple Folders are alternatives, and a combined rule requires both a selected Folder and the tag condition. Existing tag-only pages retain their saved match setting. Folder moves update matches without resaving the Playlist.
- **Quick Filter:** Select one existing device Quick Filter. Its saved criteria determine which screens match. Quick Filter membership changes update matches without resaving the Playlist.
- **Eligibility:** A page without targeting is eligible on every screen that receives the Playlist. An empty targeted rule cannot be confirmed, while a valid rule with zero matching screens can be saved; the matching-screens list is a preview. Targeting filters a page before nested content expands. Playlist assignment, Channel eligibility, schedules, and Default/Exclusive/Fallback priority still apply, so a non-matching Exclusive page cannot take over.
- **Page cards:** Targeting appears on the page card. **Copy targeting** and **Paste targeting** reuse a rule on another unlocked page while preserving its other settings.

### Collection Playback (Nested Collections)

**Applies to:** Media folders, Slide folders, Paginated Slides, nested playlists, PDFs within playlist items

#### Architecture

**Main Playlist:** Sequential playback, no "Play elements" setting
**"Play elements":** Only for nested collections (media folders, Slide folders, Paginated Slides, nested playlists, PDFs)
**Graph model:** Each collection node maintains independent state

#### Collection Types & Nesting

**Media Folder:**
- CAN contain: Media files (images, videos, audio), PDFs (page collections)
- CANNOT contain: Nested playlists, nested content, subfolders (auto-flattened)
- Count collections: Relevant ONLY for PDFs (PDF = page collection)

**Slide Folder:**
- In Playlist editor **Slides**, drag a Content folder into the Playlist; the page is labeled **Slide folder**
- Resolves Slides recursively from the selected Content folder and its subfolders at playback; excludes nested Playlists and multi-page Content
- **Play slides of folder** controls: One item, All item, Specific; also supports ordering, shuffle, and maximum Slide duration
- Folder changes are picked up through normal content-group refresh; the parent Playlist does not need rebuilding
- Lite devices skip Slide folder pages

**Playlist:**
- CAN contain: Media files, Slides, Slide folders, nested playlists, media folders (as items)
- Full nesting support

#### Play Elements Configuration

| Mode | Behavior | State Advance |
|------|----------|---------------|
| **One item** | Current item contributes to flatten | When 1 item played from collection |
| **All items** | All items contribute to flatten | When N items played (N=total) |
| **Specific N** | N items contribute to flatten | When N items played |

#### Graph State Model

```
Parent Collection
├─ Simple Element (media file, no state)
└─ Nested Collection (has state)
   ├─ State: Current iteration position
   ├─ Tracking: Played count / Configured amount
   └─ Advances: When played count == configured amount
```

**State Advance Rule:** Nested collection state advances ONLY when configured amount played from flattened list.

#### Count Collections as Single Elements

**Setting location:** Playlist item "Play elements of folder" → "Specific" mode reveals toggle

**Flatten:** Nested collection hierarchy → sequential item array. Each collection contributes items per current state + play setting.

**OFF (Flatten Mode):**
- Flatten executes every visit using current nested states
- Nested collection's play setting determines contribution to flatten:
    - All items: All items to flattened list
    - One item: Current iteration item to flattened list
    - Specific N: N items to flattened list
- Parent's play setting controls how many from flattened list play per visit
- State advances only when configured items played

**Example - Nested Playlist (All items):**
```
Playlist (One item, Count OFF)
├── welcome.jpg
├── Nested "Promos" (All items: [promo1, promo2, promo3])
└── closing.jpg

Flatten: [welcome, promo1, promo2, promo3, closing] = 5 elements
Parent (One item): Plays 1 per visit

Visit 1: welcome
Visit 2: promo1 ("Promos": 1/3)
Visit 3: promo2 ("Promos": 2/3)
Visit 4: promo3 ("Promos": 3/3 ✅)
Visit 5: closing

Pattern: welcome → promo1 → promo2 → promo3 → closing → repeat
```

**Example - Nested Playlist (One item):**
```
Playlist (One item, Count OFF)
├── logo.jpg
└── Nested "News" (One item: [news1, news2], state=news1)

Visit 1 Flatten: [logo, news1] (News contributes current item)
Visit 1: logo | Visit 2: news1 (News: 1/1 ✅ state→news2)

Visit 3 Flatten: [logo, news2] (News now contributes news2)
Visit 3: logo | Visit 4: news2 (News: 1/1 ✅ state→news1)

Pattern: logo → news1 → logo → news2 → repeat
```

**Critical:** Nested "One item" contributes only 1 element per visit. Element changes based on nested state.

**ON (Collection Mode):**
- Nested collection = 1 collection unit to parent
- Executes own play settings when selected
- Internal items don't increment parent counter

**Example:**
```
Playlist (One item, Count ON)
├── welcome.jpg (collection #1)
├── Nested "Promos" (All items: [promo1, promo2, promo3]) (collection #2)
└── closing.jpg (collection #3)

Visit 1: welcome
Visit 2: "Promos" executes → promo1, promo2, promo3
Visit 3: closing

Pattern: welcome → promo1,2,3 → closing → repeat
```

**Critical:** "Promos" plays all 3 items but counts as 1 collection to parent.

#### Played Elements Capped by Item Count

**Purpose:** Prevents repeat within single visit

**OFF:** Circular repeat to fill slot (5 wanted, 3 available → A,B,C,A,B)
**ON:** Stops at start position (5 wanted, 3 available → A,B,C only)

**Logic:** `If current_position == start_position AND played_count > 0: STOP`

#### Multi-Layer Nesting

**Flatten Mode:**
```
Playlist A (One item, Count OFF)
├── image.jpg
└── Nested Playlist B (One item, Count OFF)
    ├── slide1.jpg
    └── Nested Playlist C (All items: [detail1, detail2, detail3])

B flattens: [slide1, detail1, detail2, detail3]
B (One item) contributes to A based on B's current state

Visit 1 (B state=slide1): A flatten [image, slide1]
Visit 2 (B state=detail1): A flatten [image, detail1]

Playback: image → slide1 → image → detail1 → image → detail2 → image → detail3 → repeat
```

**Collection Mode:**
```
Playlist A (One item, Count ON)
├── image.jpg (collection #1)
└── Nested B (One item, Count ON) (collection #2)
    ├── slide1.jpg
    └── Nested C (All items: [detail1,2,3])

Visit 1: image
Visit 2: B executes → B plays slide1
Visit 3: image
Visit 4: B executes → B plays C → detail1,2,3

Pattern: image → slide1 → image → detail1,2,3 → repeat
```

#### State Management

| Aspect | Behavior |
|--------|----------|
| **Scope** | Per unique collection (by path/ID) |
| **Persistence** | Across visits within device session |
| **Reset** | Device restart (not disk-persistent) |
| **Shared state** | Same collection referenced multiple times = shared state |
| **Iteration** | Circular (returns to beginning at end) |
| **Advance** | Played count == Configured amount |

### Additional Settings
- Transition effects, mute audio, resolution settings, layout options
- Media asset proof of play

#### Playlist Layout Options
Functions as customizable grid/table system.

##### Default Layout
- **Grid**: 1x1 (single cell)
- **Display**: One element fills entire playlist area (3840x2160 at default resolution)
- **Customization**: Per-element Image fit option

##### Grid Layout
- **Structure**: Grid columns × Grid rows (default 3×3 = 9 cells)
- **Auto-switching**: Controls cell content rotation
  - Disabled (default): Cells cycle through playlist items
  - Enabled: Static content, no rotation
- **Grid Settings**:
  - Grid columns: 1-10 (default: 3)
  - Grid rows: 1-10 (default: 3)
  - Cell padding: pixels (default: 0)
- **Customization**: Per-element Image fit option

##### Continuous Slider Layout
- **Behavior**: Auto-scrolling ribbon from playlist elements
- **Grid Structure**:
  - Horizontal scroll (left/right): Number of cards × 1 (single row)
  - Vertical scroll (up/down): 1 × Number of cards (single column)
- **Card Settings**:
  - Slide direction (default: Right)
  - Number of cards: Visible simultaneously (default: 3)
  - Card gap: pixels (default: 3)
  - Cell padding: pixels (default: 0)
  - Border rounding: pixels (default: 0)
  - Item duration: seconds (default: 10)
  - Preload cards: For smooth animation (default: 3)
- **Customization**: Per-element Image fit option

### Proof of Play Attribution
Playlist page, channel, sub-channel levels. Analytics tracking, compliance, revenue attribution.

## Emergency Content

**Priority:** Emergency > Scheduled > Base Content

**Characteristics:**
- Instant activation, pre-cached locally
- Network-wide capability
- Multiple triggers: Manual, CAP, API, sensor

## Synchronized Playback

**Requirements:** Accurate time sync, identical content, absolute time reference

**Applications:** Video walls, multi-screen coordination

## Performance Architecture

### Displayer System
Content = JSON + assets. Rendering: Device → WebView → Displayer → Asset loading → Screen.

### Embedding Performance

**Performance Mode (recommended deep nesting):**
- Components in single process, faster, lower memory
- Limitations: Some page navigation/interactions may fail

**iFrame Mode (full functionality):**
- Separate process per embedding, full interactivity
- Cost: Higher memory, potential leaks

### Preload System

**1. Pre-load (Master):** ON = next in DOM background
**2. Video source pre-loading:** Controls background video loading
**3. Pre-loaded overlap time (ms):** Next content starts behind current, seamless handoff
**4. Trim duration by overlap:** Auto-subtract overlap from slide duration

### Video Playback

**Hardware Accelerated Player:**
- Native device player, better performance on certain devices
- No transition animations, video above all content

**HTML5 Player (default):** Full integration (animations, overlays, transitions)

### Widget-Based Duration
Content tab → "Slide duration based on:" → Select widget. Auto-adjusts (millisecond-accurate).

### Dynamic Content Flow
Content/Contents widget: "When finished, go to next page" actions. Complex self-navigating experiences.

## Template System

### 1. Central Wallboard Templates
Nexus repository, auto-sync (disableable), passive distribution.

### 2. Global Admin Templates
Admins select specific customers, copy-based (no ongoing connection), individual targeting.

### 3. Tenant-Level Templates
Local folders, live updates propagate to instances, instance-specific quick edits, read-only for end users.

## Quick Editing System

Quick Edit details live in docs/platform/content/quick-edit.md: editing contexts, quick-editable widget properties (including Image reframing and Multiline Text), Quick Edit mode, playlist inline editing, template overrides, branding-aware templates, permissions, and use cases.

## Team-Based Management

**Hierarchical:** Main content (admin), nested components (specific teams), multi-level delegation, team isolation.

**Example:**
```
Corporate Content (Admin)
├── Welcome (Admin)
├── Store Components (Store Team A)
│   ├── Store A Content
│   └── Store A Events
├── Regional (Regional Team B)
└── Emergency (Admin)
```

## User Terminology

- "Channel" vs "Campaign" (legacy)
- "Playlist" vs "Loop" (common)
- "Template" (Content OR Slide depending on structure)
