"use client"; import { AnimatePresence, motion } from "motion/react"; import { DownloadSimple, Play, Prohibit, Warning } from "@phosphor-icons/react"; import { Panel } from "@/components/ui"; import { downloadName } from "@/lib/download"; import { explainJobError } from "@/lib/errors"; import { progressPercent } from "@/lib/progress"; import { STAGE_LABEL, type Job } from "@/lib/types"; export function Queue({ jobs, selectedId, onSelect, onCancel, }: { jobs: Job[]; selectedId: string | null; onSelect: (job: Job) => void; onCancel: (job: Job) => void; }) { const running = jobs.filter((job) => !TERMINAL.has(job.stage)).length; return ( 0 ? `${running} on the desk` : undefined} className="overflow-hidden" > {jobs.length === 0 ? (

Nothing rendered yet

Write a style and some lyrics, then hit render. Every take stays here with its seed and its score so you can go back to it.

) : ( )}
); } const TERMINAL = new Set(["done", "failed", "cancelled"]); function Row({ job, selected, onSelect, onCancel, }: { job: Job; selected: boolean; onSelect: () => void; onCancel: () => void; }) { const active = !TERMINAL.has(job.stage); const failed = job.stage === "failed"; const percent = progressPercent(job); // Keep the raw text on the title attribute: the plain version is for acting // on, the original is for diagnosing. const explained = failed ? explainJobError(job.error) : null; return (
{job.stage === "done" && job.audio ? ( event.stopPropagation()} className="flex h-6 w-6 items-center justify-center rounded-console bg-void text-ink-dim transition-colors hover:text-citron" aria-label="Download this take" > ) : null} {active ? ( ) : null}
{active ? ( percent === null ? ( // No step reporting, so show motion rather than a number we guessed.
) : (
) ) : null}
); }