// 自由创作·任务卡:生成中(shimmer+平滑进度) / 失败(中文错误+重试) / 完成(悬停播放+操作)。 import { useRef } from "react"; import { Download, Heart, RotateCcw, Trash2 } from "lucide-react"; import type { FreeVideoTask } from "../../types"; import { MODE_LABELS, STATUS_LABELS, isInFlight, modelLabel } from "./constants"; function ratioStyle(ratio: string) { const [w, h] = ratio.split(":").map(Number); return { aspectRatio: w && h ? `${w} / ${h}` : "16 / 9" }; } export function GenerationCard({ task, progress, onOpen, onRetry, onToggleFavorite, onDelete, onDownload }: { task: FreeVideoTask; progress: number; onOpen: () => void; onRetry: () => void; onToggleFavorite: () => void; onDelete: () => void; onDownload: () => void; }) { const videoRef = useRef(null); const inFlight = isInFlight(task.status); const failed = task.status === "failed" || task.status === "cancelled"; const done = task.status === "succeeded" && !!task.video_url; return (
{ if (event.key === "Enter") onOpen(); } : undefined} onMouseEnter={() => { if (done) void videoRef.current?.play().catch(() => undefined); }} onMouseLeave={() => { videoRef.current?.pause(); if (videoRef.current) videoRef.current.currentTime = 0; }} > {inFlight && (
{STATUS_LABELS[task.status] || "生成中"} · {Math.round(Math.min(progress, 95))}%
)} {failed && (
失败

{task.error_message || "生成失败,请重试"}

)} {done && ( <>
{task.prompt}
// {MODE_LABELS[task.mode] || task.mode} · {modelLabel(task.model)} · {task.resolution.toUpperCase()} · {task.duration}s {task.status === "succeeded" && ` · ${Number(task.actual_cost || 0)} 积分`}
); }