import { useEffect, useMemo, useRef, useState } from 'react'; import { AlertTriangle, Check, Clock3, Download, Film, ImageIcon, Loader2, RefreshCw, Upload, WandSparkles, } from 'lucide-react'; import { toast } from 'sonner'; import { Badge } from '@/components/ui/badge'; import { Button } from '@/components/ui/button'; import { resolveImageWorkspaceAssetUrl, saveImageWorkspaceAsset, uploadImageWorkspaceAsset, } from '@/lib/image-workspace'; import { cn } from '@/lib/utils'; import { useImageWorkspaceStore } from '@/stores/image-workspace'; import type { DesignAsset, DesignGenerationTask, DesignWorkspace, } from '../../../shared/image-workspace'; import { youthCompilationIssueMessage, youthTaskIssueMessage, } from './youth-issue-copy'; const TASK_STATUS_LABELS: Record = { queued: '正在准备', running: '正在制作', succeeded: '完成了', failed: '未完成', cancelled: '已取消', }; const TASK_STAGE_LABELS: Record = { queued: '正在准备画面', preparing: '正在准备画面', submitting: '正在准备画面', generating: '正在制作', composing: '正在制作', validating: '正在检查结果', finalizing: '正在检查结果', completed: '完成了', failed: '这次没有完成', cancelled: '已取消', }; function formatExpiry(value: string): string { const timestamp = Date.parse(value); if (!Number.isFinite(timestamp)) return value; return new Date(timestamp).toLocaleString([], { month: 'numeric', day: 'numeric', hour: '2-digit', minute: '2-digit', }); } function AssetPreview({ asset }: { asset: DesignAsset }) { const [resolution, setResolution] = useState<{ contentPath: string; source: string | null; failed: boolean; }>(() => ({ contentPath: asset.contentPath, source: null, failed: false })); const currentResolution = resolution.contentPath === asset.contentPath ? resolution : { contentPath: asset.contentPath, source: null, failed: false }; useEffect(() => { let active = true; void resolveImageWorkspaceAssetUrl(asset.contentPath) .then((url) => { if (active) setResolution({ contentPath: asset.contentPath, source: url, failed: false }); }) .catch(() => { if (active) setResolution({ contentPath: asset.contentPath, source: null, failed: true }); }); return () => { active = false; }; }, [asset.contentPath]); if (!currentResolution.source || currentResolution.failed) { return (
{asset.mediaType === 'video' ? : }
); } if (asset.mediaType === 'video') { return (