# GlitchPlayer Integration Insights For GnommoEditor

This note is based on reading the current GnommoEditor frontend and backend, and comparing it to the current GlitchPlayer public API and data contracts.

## Short Version

GnommoEditor and GlitchPlayer are already close enough to integrate cleanly, but there are two different integration cases and they should not be solved with the exact same component:

1. Full presentation playback / slide-targeted preview inside the editor
2. Lightweight slide thumbnails inside the slide list and editing UI

The full player case is almost ready now.

The thumbnail case should get its own dedicated exported component from GlitchPlayer instead of embedding the full video player at tiny sizes.

## What Already Lines Up Well

### On the editor side

These files already create a strong seam for player integration:

- [src/pages/VideoEditorPage.jsx](/Users/jenstandstad/Projects/gnommoeditor/src/pages/VideoEditorPage.jsx)
- [backend/src/routes/videos.js](/Users/jenstandstad/Projects/gnommoeditor/backend/src/routes/videos.js)
- [backend/src/routes/slides.js](/Users/jenstandstad/Projects/gnommoeditor/backend/src/routes/slides.js)
- [backend/migrations/002_create_slides.cjs](/Users/jenstandstad/Projects/gnommoeditor/backend/migrations/002_create_slides.cjs)

The editor already stores:

- `component_key`
- `props`
- `display_mode`
- `presenter_notes`
- `start_time_sec`
- `end_time_sec`
- ordered narration segments

That is fundamentally the right shape.

### On the player side

These files define the reusable runtime surface:

- [src/player/index.ts](/Users/jenstandstad/Projects/gnommoplayer/src/player/index.ts)
- [src/components/LecturePlayer.tsx](/Users/jenstandstad/Projects/gnommoplayer/src/components/LecturePlayer.tsx)
- [src/types/lecture.ts](/Users/jenstandstad/Projects/gnommoplayer/src/types/lecture.ts)
- [packages/slide-contracts/src/templates.ts](/Users/jenstandstad/Projects/gnommoplayer/packages/slide-contracts/src/templates.ts)

The player already supports:

- full playback mode
- `mode="slide-preview"`
- `targetSlideId`
- shared slide contract types
- registry-driven slide rendering

That means the full preview case is mostly a data-shaping and packaging task, not a product rethink.

## Main Mismatches Right Now

### 1. Editor template keys do not match player template keys

The editor currently uses older local template definitions in [src/data/slideTemplates.js](/Users/jenstandstad/Projects/gnommoeditor/src/data/slideTemplates.js), including keys like:

- `TitleSlide`
- `ContentSlide`
- `BulletSlide`
- `ImageSlide`
- `QuoteSlide`

The player currently uses shared contract keys from [packages/slide-contracts/src/templates.ts](/Users/jenstandstad/Projects/gnommoplayer/packages/slide-contracts/src/templates.ts):

- `SquareYellow`
- `FullscreenSplit`
- `EquationFocus`
- `QuoteImage`
- `ChartSingle`
- `ProcessFlow`
- `DefinitionCard`

This is the most important mismatch to fix first.

### 2. The editor export route is close, but not rich enough yet

The current export route in [backend/src/routes/videos.js](/Users/jenstandstad/Projects/gnommoeditor/backend/src/routes/videos.js) at `GET /api/videos/:id/export` already builds a GlitchPlayer-style payload, but it is still missing some fields the player will want for deeper integration:

- slide `id`
- segment `id`
- glitch slide `id`
- orientation
- variant arrays beyond a single score-1 candidate
- `latexString` on equation slides as first-class data

Right now the route mostly emits one synthetic candidate per slide:

- `componentKey: s.component_key`
- `props: s.props || {}`
- `score: 1`

That is enough for a first playback integration, but not enough for a mature editor + player loop.

### 3. The thumbnail use case is not the same thing as slide preview mode

`mode="slide-preview"` in GlitchPlayer is useful for previewing a chosen slide in context, but it is still fundamentally a player runtime with:

- stage layout
- video region
- scrubber and chrome behavior
- gesture state

For editor thumbnails, that is too heavy.

What the editor really needs is a dedicated slide-only renderer.

## Recommended Integration Model

## Case 1: Full player integration inside GnommoEditor

### Recommended use

Use GlitchPlayer inside the editor for:

- a presentation preview panel
- a slide-targeted preview panel
- a “play current presentation” mode
- a “jump to this slide in player” editing workflow

### Recommended host surface

In GnommoEditor, add a React wrapper component such as:

- `src/components/GlitchPlayerPanel.jsx`

That wrapper should:

- fetch a player-ready presentation JSON object from the backend
- pass the presentation into `GlitchPlayer`
- supply the default slide registry
- own any editor-specific surrounding chrome

### Recommended backend route

Keep the current export route as the starting point, but rename or mirror it to a more intentional player route:

- `GET /api/presentations/:presentationId`

or

- `GET /api/videos/:id/player`

That keeps the seam aligned with GlitchPlayer naming and makes later migration into GnommoWeb or other runtimes easier.

### Required payload upgrades

The backend route should emit this minimum shape consistently:

```ts
{
  id: string;
  title: string;
  version: string;
  durationSec: number;
  segments: Array<{
    id: string;
    src: string;
    startTimeSec: number;
    durationSec: number;
  }>;
  slides: Array<{
    id: string;
    startTimeSec: number;
    endTimeSec?: number;
    displayMode: "square" | "fullscreen";
    glitchSlides: Array<{
      id: string;
      score: number;
      componentKey: SlideTemplateKey;
      props: SlideTemplateProps;
      latexString?: string;
      orientation?: "any" | "mobile-portrait" | "mobile-landscape" | "desktop";
    }>;
  }>;
}
```

### Important detail: stable ids

For editor integration, stable ids matter more than they do in the demo app.

Use:

- presentation `id`: `videos.gnommo_id` if available
- slide `id`: ideally `slides.gnommo_slide_id`
- glitch slide `id`: for now `${slide_id}:default`
- segment `id`: `narration_segments.segment_key`

The current export route does not include those stable ids yet. It should.

### Best first embedding point in the editor

The best initial place to integrate GlitchPlayer is [src/pages/VideoEditorPage.jsx](/Users/jenstandstad/Projects/gnommoeditor/src/pages/VideoEditorPage.jsx).

Why:

- it already loads the video, slides, and narration segments
- it is where slide timing and component selection happen
- it is where “preview current slide” is most useful

### Concrete editor workflow

Recommended behavior:

1. User edits slides in the left/main editor UI
2. Editor fetches player-ready presentation JSON
3. Right-side preview panel mounts `GlitchPlayer`
4. Clicking a slide card sets `targetSlideId`
5. The preview panel mounts:

```tsx
<GlitchPlayer
  presentation={presentation}
  slideRegistry={defaultSlideRegistry}
  mode="slide-preview"
  targetSlideId={selectedSlideId}
/>
```

This gives the editor a live preview of the exact runtime, not an approximation.

## Case 2: Slide thumbnails inside GnommoEditor

### Recommendation

Do not use the full `GlitchPlayer` for thumbnails.

Instead, add a dedicated GlitchPlayer export such as:

- `GlitchSlideThumbnail`

or

- `GlitchSlideRenderer`

### Why this should be separate

Thumbnails need to be:

- cheap to render
- deterministic
- slide-only
- independent from video playback
- easy to render many times in a list

The full player is optimized for:

- timeline playback
- stitched video
- gestures
- pause states
- scrubber chrome

That makes it the wrong abstraction for a slide list with 20 to 100 items.

### Suggested thumbnail component API

```tsx
<GlitchSlideThumbnail
  slide={slide}
  slideRegistry={defaultSlideRegistry}
  viewportMode="desktop"
  preferredGlitchSlideId={optionalSelectedVariantId}
  aspectRatio="square"
/>
```

or more generally:

```tsx
<GlitchSlideRenderer
  slide={slide}
  slideRegistry={defaultSlideRegistry}
  viewportMode="desktop"
  renderMode="thumbnail"
/>
```

### What the thumbnail component should do

- resolve the correct active glitch slide for a viewport
- render only the chosen slide surface
- render no video
- render no scrubber
- render no play/pause chrome
- render no vote UI
- avoid autoplay and interaction state

### Where thumbnails should be used in the editor

The first places:

- slide list cards in [src/pages/VideoEditorPage.jsx](/Users/jenstandstad/Projects/gnommoeditor/src/pages/VideoEditorPage.jsx)
- video detail slide table in [src/pages/VideoDetailPage.jsx](/Users/jenstandstad/Projects/gnommoeditor/src/pages/VideoDetailPage.jsx)
- template picker previews in [src/data/slideTemplates.js](/Users/jenstandstad/Projects/gnommoeditor/src/data/slideTemplates.js) or its replacement

### Data source for thumbnails

The editor does not need the full presentation to render thumbnails.

It only needs:

- the slide data
- the chosen or default glitch slide
- the desired viewport mode

So the thumbnail renderer can use the same slide contracts, but with a much smaller data dependency than the full player.

## Shared Contract Strategy

This should be the foundation of the integration.

### Recommended rule

GnommoEditor should stop owning its own slide template definitions as freeform local config.

Instead:

- `@gnommo/slide-contracts` becomes the single source of truth
- both repos import template keys and payload interfaces from it
- editor field forms are generated from contract metadata
- player rendering trusts the same contract

### Practical consequence

[src/data/slideTemplates.js](/Users/jenstandstad/Projects/gnommoeditor/src/data/slideTemplates.js) should eventually be replaced by a shared metadata layer derived from the contract package.

That shared metadata should include:

- `componentKey`
- display mode
- field definitions
- content budgets
- editor labels
- placeholders

That gives one definition of each slide type for:

- AI generation
- editor forms
- backend validation
- player rendering

## Recommended Implementation Plan

## Phase 1: Full preview integration

Goal: mount GlitchPlayer in GnommoEditor with minimal risk.

1. Add GlitchPlayer as a local workspace dependency or sibling package dependency
2. Add `@gnommo/slide-contracts` to the editor too
3. Upgrade `GET /api/videos/:id/export` to include stable ids and player-complete fields
4. Add a preview panel to [src/pages/VideoEditorPage.jsx](/Users/jenstandstad/Projects/gnommoeditor/src/pages/VideoEditorPage.jsx)
5. Wire slide-card click to `targetSlideId`

This gives immediate value with very little duplicated logic.

## Phase 2: Shared slide schema adoption

Goal: make editor and player speak exactly the same slide language.

1. Replace local editor template keys with shared keys
2. Add per-template form metadata to the shared contracts package
3. Make editor slide creation and editing use shared contract names
4. Validate slide payloads before save

This is the phase that prevents long-term drift.

## Phase 3: Thumbnail renderer

Goal: make the slide list visually accurate and lightweight.

1. Export `GlitchSlideThumbnail` or `GlitchSlideRenderer` from GlitchPlayer
2. Reuse player slide registry and resolution logic
3. Render only the slide surface
4. Drop all playback chrome and video dependencies
5. Use it in the editor slide list and detail pages

This will make the editor feel much more aligned with the actual player runtime.

## Phase 4: Variant-aware editing

Goal: prepare for many candidate glitch slides per logical slide.

1. Extend editor data model from “one `component_key` + `props` per slide” to:
   - one logical slide
   - many glitch slide variants
2. Add `score`, `orientation`, and `variant id`
3. Let thumbnails preview the highest-scoring or selected variant
4. Let full player preview the exact runtime behavior

This is where GlitchPlayer and GnommoEditor become a true shared system.

## My Strong Recommendations

### Recommendation 1

Treat full player preview and slide thumbnails as two separate exported surfaces.

That keeps both integrations simple and prevents the editor from trying to use a playback runtime as a list cell.

### Recommendation 2

Use the editor backend export route as the canonical bridge, but strengthen it.

The route in [backend/src/routes/videos.js](/Users/jenstandstad/Projects/gnommoeditor/backend/src/routes/videos.js) is already the right place to centralize this mapping.

### Recommendation 3

Replace local editor slide template config with shared contract-driven metadata as soon as possible.

That is the most important architectural step if you want AI agents, human editors, and GlitchPlayer to all agree on what a slide is.

## Suggested Next Tasks

If we want to execute this plan incrementally, I would do these next in order:

1. Upgrade the editor export route to emit stable ids and proper glitch slide objects
2. Mount GlitchPlayer in `VideoEditorPage` as a slide-targeted preview panel
3. Add a new exported `GlitchSlideThumbnail` component in GnommoPlayer
4. Replace editor-local slide template definitions with shared metadata from `@gnommo/slide-contracts`

That sequence gives fast value first, while keeping the long-term architecture clean.
