"use client"; import { memo } from "react"; import { ChevronDown, Grid2x2, CircleDot } from "lucide-react"; import { cn } from "@/lib/utils"; type ColorTheme = "purple" | "blue" | "green" | "orange" | "red"; interface ImageGenerationLoadingProps { imageCount?: number; maxImages?: number; colorTheme?: ColorTheme; modelName?: string; providerType?: string; phase?: "idle" | "queued" | "processing" | "finalizing" | "failed"; elapsedSeconds?: number; } const PROVIDER_MODEL_LABEL: Record = { "alibaba-image": "千问图片", "ruxa-image": "RUXA 图片", "fal-image": "FAL 图片", "openai-image": "OpenAI 图片", midjourney: "Midjourney", "volcano-vision": "即梦 4.5", gemini: "Gemini 图片", }; const PHASE_HINT: Record, string> = { idle: "任务已创建,正在初始化生成参数。", queued: "任务已进入队列,请稍候。", processing: "模型正在生成图片,请稍候。", finalizing: "图片已生成完成,正在同步到对话。", failed: "生成失败,请重试。", }; export const ImageGenerationLoading = memo( ({ imageCount = 1, maxImages = 6, modelName, providerType, phase = "processing", elapsedSeconds = 0, }: ImageGenerationLoadingProps) => { const count = Math.min(Math.max(imageCount, 1), maxImages); const resolvedModelName = modelName?.trim() || PROVIDER_MODEL_LABEL[providerType || ""] || "AI 图片模型"; const estimateRangeLabel = "60~120秒"; const elapsedLabel = elapsedSeconds > 0 ? `已等待 ${elapsedSeconds}s` : `预计 ${estimateRangeLabel}`; const isFailed = phase === "failed"; return (
开始生成
{resolvedModelName}
1 && "grid-cols-2" )} > {count === 1 ? ( <>
) : ( Array.from({ length: count }).map((_, index) => (
)) )}
{isFailed ? "生成失败" : "设计图处理中"}
使用 {resolvedModelName} 生成图片,预计 {estimateRangeLabel}
{(phase !== "processing" || elapsedSeconds > 0) && (
{PHASE_HINT[phase]} {elapsedLabel}
)}
); } ); ImageGenerationLoading.displayName = "ImageGenerationLoading";