6.8 KiB
Slide Preview Integration Guide
This guide is for integrating an authoritative slide preview into another React + Vite UI, using the real GlitchPlayer runtime rather than a custom thumbnail or placeholder renderer.
Goal
When the editor user selects a slide, the preview should be:
- the real
GlitchPlayer - moved to the selected slide
- paused on that slide
- rendered with the same layout, video, timing, and slide runtime as the final presentation
This is the correct preview surface when fidelity matters more than efficiency.
Use This, Not A Custom Thumbnail
For the main preview panel:
- use
GlitchPlayer - with
mode="slide-preview" - and
targetSlideId
Do not use:
GlitchSlideThumbnailGlitchSlideRenderer- a hand-built editor preview
Those are useful for slide lists and lightweight surfaces, but not for the authoritative preview.
Built Files To Consume
If the integration agent is only allowed to fetch built artifacts from this repo, use:
Build them with:
npm run build
That command now produces both the demo app build and the vendor bundle.
What To Import
From gnommoplayer.js, the preview integration should import:
GlitchPlayerdefaultSlideRegistry
From gnommoplayer.css, import the player stylesheet once near the app root.
Example:
import "../vendor/gnommoplayer/gnommoplayer.css";
import {
GlitchPlayer,
defaultSlideRegistry,
} from "../vendor/gnommoplayer/gnommoplayer.js";
Required Data
The preview must receive a full presentation object, not just one slide.
That presentation should include:
idtitleversiondurationSecsegmentsslides
Why:
- the player needs the full timeline
- the player needs the talking-head video segments
- the player derives the active slide from presentation timing
- the player must match the final runtime, not a simplified editor view
Preview Contract
The preview panel should render the player like this:
<GlitchPlayer
presentation={presentation}
slideRegistry={defaultSlideRegistry}
mode="slide-preview"
targetSlideId={selectedSlideId}
initialSessionId={`editor-preview-${presentation.id}`}
/>
Behavior of this mode:
- the player jumps to the targeted slide’s
startTimeSec - playback starts paused
- the real player UI and layout are used
- the talking-head video is still part of the runtime surface
Recommended Host Component
The host app should wrap this in a dedicated preview component.
Example:
import { useEffect, useState } from "react";
import "../vendor/gnommoplayer/gnommoplayer.css";
import {
GlitchPlayer,
defaultSlideRegistry,
} from "../vendor/gnommoplayer/gnommoplayer.js";
export function SlidePreviewPanel({
presentationId,
selectedSlideId,
}: {
presentationId: string;
selectedSlideId: string | null;
}) {
const [presentation, setPresentation] = useState(null);
const [error, setError] = useState(null);
useEffect(() => {
let cancelled = false;
fetch(`/api/videos/${presentationId}/export`)
.then((response) => {
if (!response.ok) {
throw new Error(`Preview fetch failed: ${response.status}`);
}
return response.json();
})
.then((data) => {
if (!cancelled) {
setPresentation(data);
setError(null);
}
})
.catch((caughtError) => {
if (!cancelled) {
setError(String(caughtError));
}
});
return () => {
cancelled = true;
};
}, [presentationId]);
if (error) {
return <div>Preview error: {error}</div>;
}
if (!presentation || !selectedSlideId) {
return <div>Select a slide to preview.</div>;
}
return (
<div style={{ width: "100%", height: "100%" }}>
<GlitchPlayer
presentation={presentation}
slideRegistry={defaultSlideRegistry}
mode="slide-preview"
targetSlideId={selectedSlideId}
initialSessionId={`editor-preview-${presentation.id}`}
/>
</div>
);
}
How The Editor Should Drive It
The editor should keep one piece of selection state:
selectedSlideId
When the user clicks a slide in the editor:
- update
selectedSlideId - keep the same
presentation - re-render
GlitchPlayerwith the newtargetSlideId
That is enough for the player to move to the correct slide.
Important Implementation Notes
1. Use The Full Presentation
Do not try to construct a fake one-slide presentation for preview.
That creates drift in:
- timing
- fullscreen transitions
- video positioning
- segment masking
- variant behavior
The preview should be the real timeline.
2. It Is Fine If The Video Loads Again
That is an acceptable tradeoff for now.
The goal of the editor preview is correctness:
- same player
- same slide runtime
- same layout
Not maximum efficiency.
3. Keep Thumbnails Separate
This preview guide is only for the main preview panel.
For slide list cards:
GlitchSlideThumbnailis still appropriate
For the large “truth” preview:
- use
GlitchPlayer
4. Prefer Stable Slide Ids
The editor should pass a stable selectedSlideId, ideally the same id used in the exported presentation payload.
The preview mechanism depends on exact id matching:
targetSlideId={selectedSlideId}
5. Do Not Replace The Player’s Internal Registry Logic
Use:
slideRegistry={defaultSlideRegistry}
unless the host intentionally provides a superset registry.
The preview should not invent its own runtime component resolution.
When To Use GlitchSlideThumbnail Instead
Use GlitchSlideThumbnail only for:
- slide list rows
- compact cards
- mini previews in inspector sidebars
Do not use it as a substitute for the main preview panel.
Recommended Replacement Strategy
If the current editor preview is “kind of not working,” replace it with this sequence:
- Keep the slide list as-is for now
- Remove the custom preview widget
- Add a dedicated preview panel component
- Fetch the full exported presentation JSON
- Render:
<GlitchPlayer
presentation={presentation}
slideRegistry={defaultSlideRegistry}
mode="slide-preview"
targetSlideId={selectedSlideId}
/>
That gives you a preview surface that is as close to final runtime as possible.
Short Handoff Note
If you need the shortest possible instruction for the other agent, use this:
Use the real player for slide preview, not the thumbnail renderer. Import GlitchPlayer and defaultSlideRegistry from dist/vendor/gnommoplayer.js, import dist/vendor/gnommoplayer.css, fetch the full presentation JSON, and render GlitchPlayer with mode="slide-preview" and targetSlideId={selectedSlideId}.