import { useEffect, useRef, useState } from "react"; import type { VideoTemplate } from "../../api/types"; /** Portrait (9:16) video format. */ export function PhoneIcon() { return ( ); } /** Landscape (16:9) video format. */ export function ScreenIcon() { return ( ); } /** One audio element for the whole page: play a URL (or a Blob), stop the previous one. */ export function useAudio() { const audio = useRef(null); const objectUrl = useRef(null); const [playing, setPlaying] = useState(null); const stop = () => { audio.current?.pause(); if (objectUrl.current) URL.revokeObjectURL(objectUrl.current); objectUrl.current = null; setPlaying(null); }; useEffect(() => stop, []); function play(key: string, src: string | Blob | null | undefined) { if (!src) return; const again = playing === key; stop(); if (again) return; let url = typeof src === "string" ? src : URL.createObjectURL(src); if (typeof src !== "string") objectUrl.current = url; if (typeof src === "string" && !/^(https?:|data:|blob:|\/)/.test(src)) url = `data:audio/mpeg;base64,${src}`; audio.current = new Audio(url); audio.current.onended = () => setPlaying(null); audio.current.play().catch(() => setPlaying(null)); setPlaying(key); } return { playing, play, stop }; } export function PlayButton({ on, disabled, label, onClick }: { on: boolean; disabled?: boolean; label: string; onClick: () => void }) { return ( ); } /** A file picker that shows what was picked. */ export function FilePick({ accept, multiple, label, hint, onPick }: { accept: string; multiple?: boolean; label: string; hint?: string; onPick: (files: File[]) => void; }) { return ( ); } /** A template's poster (portrait or landscape, to match the video), or its colors when it has none. */ export function TemplateThumb({ template, portrait = false, large = false }: { template: VideoTemplate; portrait?: boolean; large?: boolean; }) { const src = (portrait && template.preview_portrait_url) || template.preview_url || null; const [failed, setFailed] = useState(null); const c = template.preview_colors ?? {}; if (!src || failed === src) { return (
{template.name}
); } return setFailed(src)} />; }