caaa333f02
Deploy / deploy (push) Failing after 19m11s
Two independent features landing together: Generated shot thumbnails — a shot can now carry a thumbnail promoted from a render export (Shot.generatedThumbnailUrl/generatedThumbnailFrom) alongside the existing brief-supplied thumbnailUrl, which always takes display precedence (lib/shot-thumbnail.ts) so a promoted frame can only ever fill a gap, never overwrite the brief. Shows with pipelineConfig.autoShotThumbnail promote automatically on every finished export (lib/render-pipeline/preview.ts); promoteExportThumbnail/ clearGeneratedThumbnail (actions/shots.ts) are the manual equivalent for everyone else. Worker-side seek logic for picking the promoted frame is covered by RenderWorker/VFXReviewWorker.Tests/ThumbnailSeekTests.cs. Bulk shot delete — the shot-status page's selection bar gets a "Bulk Actions" dropdown (alongside the existing Change Due Date) with Delete Shots. bulkDeleteShots() (actions/shots.ts) deletes one at a time rather than in a single statement: exports_shotId_fkey is ON DELETE RESTRICT by design, so a shot with renders or deliveries on record is protected and gets skipped and reported by name rather than aborting the whole selection or being silently destroyed along with its history. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
42 lines
1.7 KiB
TypeScript
42 lines
1.7 KiB
TypeScript
/**
|
|
* Shot thumbnail resolution.
|
|
*
|
|
* A shot can carry two stills:
|
|
*
|
|
* • `thumbnailUrl` — the reference frame supplied with the brief
|
|
* (client still, batch upload, ext API). Editorial
|
|
* data: only ever written by a human.
|
|
* • `generatedThumbnailUrl` — a frame promoted from a render export, either
|
|
* automatically (projects with
|
|
* `pipelineConfig.autoShotThumbnail`) or by hand.
|
|
*
|
|
* The reference always wins. Shows that arrive with stills look exactly as they
|
|
* do today; shows that arrive without any get their empty grids filled from the
|
|
* renders instead. Because the two live in different columns, a promotion can
|
|
* never destroy the reference — clearing the generated one always falls back to
|
|
* the brief.
|
|
*/
|
|
export interface ShotThumbnailFields {
|
|
thumbnailUrl?: string | null;
|
|
generatedThumbnailUrl?: string | null;
|
|
}
|
|
|
|
/** The still to display for a shot, or null when it has neither. */
|
|
export function shotThumbnail(shot: ShotThumbnailFields | null | undefined): string | null {
|
|
return shot?.thumbnailUrl || shot?.generatedThumbnailUrl || null;
|
|
}
|
|
|
|
/** True when the displayed still came from a render rather than the brief. */
|
|
export function isGeneratedThumbnail(shot: ShotThumbnailFields | null | undefined): boolean {
|
|
return !shot?.thumbnailUrl && !!shot?.generatedThumbnailUrl;
|
|
}
|
|
|
|
/**
|
|
* Prisma `select` fragment for the two columns. Spread it wherever a query
|
|
* already selects `thumbnailUrl` so the fallback has something to fall back to.
|
|
*/
|
|
export const shotThumbnailSelect = {
|
|
thumbnailUrl: true,
|
|
generatedThumbnailUrl: true,
|
|
} as const;
|