diff --git a/packages/studio/src/components/renders/RenderQueueItem.tsx b/packages/studio/src/components/renders/RenderQueueItem.tsx index 220a245233..b1d7c6cead 100644 --- a/packages/studio/src/components/renders/RenderQueueItem.tsx +++ b/packages/studio/src/components/renders/RenderQueueItem.tsx @@ -1,6 +1,4 @@ import { memo, useCallback, useState, useEffect, useRef } from "react"; -import { ExpandOnHover } from "../ui/ExpandOnHover"; -import { ExpandedVideoPreview } from "../ui/ExpandedVideoPreview"; import type { RenderJob } from "./useRenderQueue"; interface RenderQueueItemProps { @@ -21,7 +19,7 @@ function formatTimeAgo(timestamp: number): string { return `${Math.floor(diff / 3600000)}h ago`; } -/** Extracts a single JPEG frame from a video URL using a hidden video + canvas. */ +/** Static frame extracted once via hidden video + canvas. */ function RenderThumbnail({ src }: { src: string }) { const [frame, setFrame] = useState(null); const didExtract = useRef(false); @@ -44,7 +42,6 @@ function RenderThumbnail({ src }: { src: string }) { }; video.addEventListener("loadedmetadata", () => { - // Seek to ~10% in so we get a representative non-black frame video.currentTime = Math.min(2, video.duration * 0.1 || 2); }); @@ -58,7 +55,6 @@ function RenderThumbnail({ src }: { src: string }) { }); video.addEventListener("error", cleanup); - video.src = src; video.load(); @@ -94,22 +90,45 @@ export const RenderQueueItem = memo(function RenderQueueItem({ ); const viewSrc = `/api/render/${job.id}/view`; + const isComplete = job.status === "complete"; - const row = ( + return (
setHovered(true)} onPointerLeave={() => setHovered(false)} + onClick={isComplete ? handleOpen : undefined} className={[ "px-3 py-2.5 border-b border-neutral-800/30 last:border-0 transition-colors duration-150", - job.status === "complete" ? "cursor-pointer hover:bg-neutral-800/30" : "", + isComplete ? "cursor-pointer hover:bg-neutral-800/30" : "", ] .filter(Boolean) .join(" ")} >
- {/* Thumbnail — matches CompCard sizing (w-20 h-[45px]) */} + {/* Thumbnail — static frame; swaps to live video on hover */}
- {job.status === "complete" && } + {isComplete && ( + <> + {/* Live video — visible on hover */} + {hovered && ( +