/** * Timeline Preview Integration * Integrates real-time preview with Media Studio timeline */ import { Eye, EyeOff, Monitor, Settings, Zap } from "lucide-react" import { useEffect, useRef } from "react" import { Badge } from "@/components/ui/badge" import { Button } from "@/components/ui/button" import { Card } from "@/components/ui/card" import { useRealtimePreview } from "../hooks/use-realtime-preview" import { QualityControls } from "./quality-controls" interface TimelinePreviewIntegrationProps { /** * Position in the timeline layout */ position?: "sidebar" | "overlay" | "panel" /** * Size constraint */ maxWidth?: number maxHeight?: number /** * Show controls */ showControls?: boolean /** * Enable/disable preview */ enabled?: boolean /** * Callback when preview state changes */ onPreviewChange?: (enabled: boolean) => void className?: string } export function TimelinePreviewIntegration({ position = "panel", maxWidth = 400, maxHeight = 300, showControls = true, enabled = true, onPreviewChange, className, }: TimelinePreviewIntegrationProps) { const containerRef = useRef(null) const { canvasRef, videoRef, previewFrame, isInitialized, gpuTier, quality, setQuality, cacheStats } = useRealtimePreview({ cacheSize: 50, // Smaller cache for timeline integration prefetchRange: 1, // Less aggressive prefetching updateInterval: position === "overlay" ? 16 : 33, // Higher fps for overlay }) // Adjust canvas size based on container useEffect(() => { if (!containerRef.current) return const resizeObserver = new ResizeObserver((entries) => { const entry = entries[0] const { width, height } = entry.contentRect // Calculate constrained size const aspectRatio = 16 / 9 let canvasWidth = Math.min(width - 32, maxWidth) // Account for padding let canvasHeight = canvasWidth / aspectRatio if (canvasHeight > maxHeight) { canvasHeight = maxHeight canvasWidth = canvasHeight * aspectRatio } // Update canvas size would be handled by the canvas ref // This is just for demonstration of the sizing logic }) resizeObserver.observe(containerRef.current) return () => resizeObserver.disconnect() }, [maxWidth, maxHeight]) const getPositionStyles = () => { switch (position) { case "overlay": return "absolute top-4 right-4 z-50 max-w-sm shadow-2xl border-2" case "sidebar": return "sticky top-4" default: return "" } } const handleTogglePreview = () => { const newState = !enabled onPreviewChange?.(newState) } if (!enabled) { return (
Preview Disabled
) } return ( {/* Header */} {showControls && (
Live Preview {isInitialized && ( Live )}
{gpuTier.toUpperCase()}
)} {/* Preview Canvas */}
{/* Hidden video element */}