Files
vfxreview/components/player/HandleBadge.tsx
T
twotalesanimation 2e9fa45580
Deploy / deploy (push) Successful in 3m31s
feat(review): flag handles in the review player (metadata only)
Renders run 8 frames past the cut at each end. Directors were flagging
glitches in unfixed handles as shot problems, so the player now marks
them — without trimming or burning anything into the EXRs/MOV/MP4.

- Version.handleHead/handleTail/pictureStartFrame, Export.handleHead/
  handleTail; migration backfills pipeline exports and their preview
  versions from the manifest's handleFrames (else 8)
- AE panel: "Includes handles [8] frames each end" -> manifest.review;
  older manifests fall back to source.handleFrames
- finalize copies handles onto the Version; worker 1.6.4 reports the
  head slate length (pictureStartSeconds), else the player infers it
  as MP4 frames - EXR frameCount
- Player: hatched HANDLE / SLATE regions and cut marks on the timeline,
  "HEAD/TAIL HANDLE · NOT IN EDIT" overlay on handle frames, HANDLE badge
  on notes, "Edit range only" toggle (default on in the client portal)
- Staff Handles editor on the review page for manual uploads/corrections

Also fixes two player bugs found while testing: timeToFrame floored
float error (every seek landed a frame early), and J/reverse never ran
(the keyboard effect's cleanup stopped it on the next render).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-22 15:07:29 +02:00

26 lines
802 B
TypeScript

"use client";
import { useReviewStore } from "@/hooks/use-review-player";
import { isHandleFrame } from "@/lib/handles";
import { cn } from "@/lib/utils";
/**
* "HANDLE" tag for a note left on a handle frame, so whoever picks it up can
* see at a glance that it's about a frame outside the edit.
*/
export function HandleBadge({ frame, className }: { frame: number; className?: string }) {
const editRange = useReviewStore((s) => s.editRange);
if (!isHandleFrame(editRange, frame)) return null;
return (
<span
className={cn(
"rounded border border-amber-400/40 bg-amber-400/10 px-1 py-px font-mono text-[9px] font-bold tracking-wide text-amber-400",
className
)}
title="This frame is a handle — outside the edit"
>
HANDLE
</span>
);
}