mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-03 12:54:29 +00:00
* refactor: split useTimelinePlayer.ts and hyperframes-player.ts into focused modules (<500 LOC each) * fix(ci): scope 500 LOC check to packages/studio, add allowlist for grandfathered files * feat(cli): Linux ARM64 support — auto-install Chromium on DGX Spark / GB10 / Jetson Chrome Headless Shell has no Linux ARM64 binary. On arm64 Linux: - Detects the platform automatically - Tries to auto-install system Chromium via apt-get (works on Ubuntu/Debian ARM) - Falls back to clear manual instructions with exact commands - 'hyperframes browser ensure' guides through the setup interactively - After setup, all render commands work without any flags * fix(ci): disable Windows Defender real-time monitoring to prevent EPERM builds Path exclusions are insufficient — Defender re-scans new files created during bun install before the exclusion takes effect. Disable real-time monitoring for the entire job duration instead (standard CI practice). * refactor(studio): split all files >500 LOC + extract useToast, delete allowlist All 11 large files split into focused modules under 500 LOC. App.tsx extracted toast logic into useToast hook (493 LOC now). .filesize-allowlist deleted — no longer needed. * fix: remove unused imports from split files, extract useToast from App.tsx App.tsx: 504 → 493 lines (toast logic extracted to useToast hook) timelineDOM.ts: remove unused imports from re-export pattern MotionPanel.tsx: remove unused clampStudioCustomEasePoints import studioMotionOps.ts: remove unused StudioGsapMotionDirection import * fix(ci): use Set-MpPreference to fully disable Windows Defender (both jobs) * fix(producer): use node --experimental-strip-types instead of tsx for build:fonts Eliminates the tsx binary dependency that Windows Defender locks during bun install, causing EPERM errors. Node 22.6+ strips TypeScript types natively with no external binary. * chore: remove .filesize-allowlist — App.tsx is now 493 lines (<500) * fix(ci): disable Windows Defender before checkout to prevent all EPERM races * fix(producer): skip build:fonts if fontData.generated.ts already exists The generated file is tracked in git, so CI doesn't need to regenerate it. This avoids @fontsource/inter node_modules access on Windows which triggers EPERM from Defender scanning during bun install.
73 lines
2.3 KiB
TypeScript
73 lines
2.3 KiB
TypeScript
/**
|
|
* Helpers for wiring the player's optional UI elements: the playback controls
|
|
* bar, the poster image overlay, and input-filtering utilities.
|
|
*
|
|
* Extracted from the web component so the setup logic doesn't inflate the
|
|
* class body. These are pure imperative DOM operations; they carry no
|
|
* persistent state beyond what the caller tracks.
|
|
*/
|
|
|
|
import { createControls, type ControlsCallbacks, type ControlsOptions } from "./controls.js";
|
|
|
|
/**
|
|
* Create the playback controls overlay and attach it to `parent`.
|
|
* Returns the controls API object. A no-op guard (returns the existing API)
|
|
* must be enforced by the caller — this function always constructs.
|
|
*/
|
|
export function setupControls(
|
|
parent: ShadowRoot,
|
|
muted: boolean,
|
|
volume: number,
|
|
speedPresetsAttr: string | null,
|
|
callbacks: ControlsCallbacks,
|
|
): ReturnType<typeof createControls> {
|
|
const speedPresets = speedPresetsAttr
|
|
? speedPresetsAttr
|
|
.split(",")
|
|
.map(Number)
|
|
.filter((n) => !isNaN(n) && n > 0)
|
|
: undefined;
|
|
const options: ControlsOptions = speedPresets ? { speedPresets } : {};
|
|
const api = createControls(parent, callbacks, options);
|
|
api.updateMuted(muted);
|
|
api.updateVolume(volume);
|
|
return api;
|
|
}
|
|
|
|
/**
|
|
* Set up or remove the poster image element in `parent`.
|
|
*
|
|
* - When `posterUrl` is non-empty, creates the `<img>` if needed and sets src.
|
|
* - When `posterUrl` is null/empty, removes the existing element (if any).
|
|
*
|
|
* Returns the current poster element (possibly newly created) or `null`.
|
|
*/
|
|
export function setupPoster(
|
|
parent: ShadowRoot,
|
|
posterUrl: string | null,
|
|
existing: HTMLImageElement | null,
|
|
): HTMLImageElement | null {
|
|
if (!posterUrl) {
|
|
existing?.remove();
|
|
return null;
|
|
}
|
|
if (!existing) {
|
|
existing = document.createElement("img");
|
|
existing.className = "hfp-poster";
|
|
parent.appendChild(existing);
|
|
}
|
|
existing.src = posterUrl;
|
|
return existing;
|
|
}
|
|
|
|
/**
|
|
* Returns `true` when `event` originated inside an `hfp-controls` element.
|
|
* Used to prevent the bare-player-surface click handler from double-firing
|
|
* when the user clicks an overlay control button.
|
|
*/
|
|
export function isControlsClick(event: Event): boolean {
|
|
return event
|
|
.composedPath()
|
|
.some((t) => t instanceof HTMLElement && t.classList.contains("hfp-controls"));
|
|
}
|