Skip to content

Commit 86eea2b

Browse files
committed
feat(player): <hyperframes-slideshow> web component + presenter
Stack-split from the original ss-player PR (#1581): the <hyperframes-slideshow> custom element (wraps <hyperframes-player>, drives the controller), presenter/audience BroadcastChannel sync, nav chrome, and the player scenes hook.
1 parent aa9036b commit 86eea2b

7 files changed

Lines changed: 2381 additions & 1 deletion

packages/player/src/hyperframes-player.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ class HyperframesPlayer extends HTMLElement {
8989
private _directTimelineClock: DirectTimelineClock;
9090
private _parentTickRaf: number | null = null;
9191
private _media: ParentMediaManager;
92+
private _scenes: { id: string; start: number; duration: number }[] = [];
9293

9394
constructor() {
9495
super();
@@ -261,6 +262,12 @@ class HyperframesPlayer extends HTMLElement {
261262
return this.iframe;
262263
}
263264

265+
/** Scene list from the last-received runtime timeline message. Empty until
266+
* the composition runtime fires its first "timeline" postMessage. */
267+
get scenes(): { id: string; start: number; duration: number }[] {
268+
return this._scenes;
269+
}
270+
264271
play() {
265272
this.posterEl?.remove();
266273
this.posterEl = null;
@@ -586,6 +593,9 @@ class HyperframesPlayer extends HTMLElement {
586593
sendControl: (action, extra) => this._sendControl(action, extra),
587594
getIframeDoc: () => this.iframe.contentDocument,
588595
onRuntimeReady: () => this._replayBridgeState(),
596+
setScenes: (scenes) => {
597+
this._scenes = scenes;
598+
},
589599
updateControlsTime: (t, d) => this.controlsApi?.updateTime(t, d),
590600
updateControlsPlaying: (p) => this.controlsApi?.updatePlaying(p),
591601
dispatchEvent: (ev) => this.dispatchEvent(ev),

packages/player/src/runtime-message-handler.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ const makeCallbacks = (): MessageHandlerCallbacks => ({
1818
media: { mirrorTime: vi.fn(), promoteToParentProxy: vi.fn() } as unknown as ParentMediaManager,
1919
getPlaybackState: vi.fn(() => ({ currentTime: 0, duration: 0, paused: true, lastUpdateMs: 0 })),
2020
setPlaybackState: vi.fn(),
21+
setScenes: vi.fn(),
2122
getShaderLoadingMode: vi.fn(() => "auto"),
2223
shaderLoader: { update: vi.fn() } as unknown as ShaderLoaderState,
2324
setCompositionSize: vi.fn(),

packages/player/src/runtime-message-handler.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,16 @@ import type { ShaderTransitionState } from "./shader-options.js";
1515

1616
const FPS = 30;
1717

18+
type SceneRecord = { id: string; start: number; duration: number };
19+
20+
function extractScenes(raw: unknown): SceneRecord[] {
21+
if (!Array.isArray(raw)) return [];
22+
return (raw as SceneRecord[]).filter(
23+
(s) =>
24+
typeof s.id === "string" && typeof s.start === "number" && typeof s.duration === "number",
25+
);
26+
}
27+
1828
export interface MessageHandlerCallbacks extends PlaybackStateCallbacks {
1929
getPlaybackState: () => PlaybackState;
2030
setPlaybackState: (next: PlaybackState) => void;
@@ -27,8 +37,11 @@ export interface MessageHandlerCallbacks extends PlaybackStateCallbacks {
2737
* uses it to replay current bridge state (mute, volume, playback rate) so
2838
* control messages sent before the iframe's listener registered aren't lost. */
2939
onRuntimeReady: () => void;
40+
/** Called with the scene list whenever a "timeline" message is received. */
41+
setScenes: (scenes: SceneRecord[]) => void;
3042
}
3143

44+
// fallow-ignore-next-line complexity
3245
export function handleRuntimeMessage(
3346
event: MessageEvent,
3447
frameWindow: Window | null,
@@ -90,6 +103,7 @@ export function handleRuntimeMessage(
90103
callbacks.setPlaybackState({ ...pb, duration });
91104
callbacks.updateControlsTime(pb.currentTime, duration);
92105
}
106+
callbacks.setScenes(extractScenes(data["scenes"]));
93107
return;
94108
}
95109

0 commit comments

Comments
 (0)