auto-save 2026-05-13 09:54 (~3)
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
import { useEffect, useState } from "react"
|
||||
import { createPortal } from "react-dom"
|
||||
import { X, ChevronLeft, ChevronRight, Check, Sparkles, Wand2, Loader2, Eye, RefreshCw, Plus } from "lucide-react"
|
||||
import { frameUrl, describeFrame, translateText, generateImage, generatedImageUrl, type KeyFrame, type Job } from "@/lib/api"
|
||||
import { frameUrl, describeFrame, translateText, generateImage, type KeyFrame, type Job } from "@/lib/api"
|
||||
import { toast } from "sonner"
|
||||
|
||||
type CustomItem = { id: string; zh: string; en: string; translating: boolean }
|
||||
@@ -96,12 +96,12 @@ export function FrameLightbox({ jobId, frames, activeIndex, selected, onClose, o
|
||||
const updated = await generateImage(jobId, f.index, {
|
||||
prompt: base,
|
||||
extra_prompt: extraEn,
|
||||
negative_prompt: "水印, @用户名, TikTok logo, 平台文字, 浮水印",
|
||||
negative_prompt: "watermark, username text, social media handle, platform logo, overlay text, captions",
|
||||
model: "gemini-3-pro-image-preview",
|
||||
mode: "edit",
|
||||
})
|
||||
onJobUpdate?.(updated)
|
||||
toast.success(`分镜 ${f.index + 1} 垫图生成完成 · 已加入生图卡`)
|
||||
toast.success(`分镜 ${f.index + 1} 垫图生成完成 → 「生图」节点查看`)
|
||||
} catch (e) {
|
||||
toast.error("生图失败:" + (e instanceof Error ? e.message : String(e)))
|
||||
} finally {
|
||||
@@ -356,44 +356,6 @@ export function FrameLightbox({ jobId, frames, activeIndex, selected, onClose, o
|
||||
)}
|
||||
</section>
|
||||
|
||||
{/* 已生成的垫图(与生图卡同源) */}
|
||||
{f.generated_images && f.generated_images.length > 0 && (
|
||||
<section>
|
||||
<div className="flex items-center justify-between mb-1.5">
|
||||
<div className="flex items-center gap-1.5 text-white text-[12.5px] font-semibold">
|
||||
<Check className="h-3.5 w-3.5" />
|
||||
已生成垫图
|
||||
<span className="text-[10px] text-white/35 font-mono">· {f.generated_images.length}</span>
|
||||
</div>
|
||||
<span className="text-[9.5px] text-white/35">同步到 →「生图」节点</span>
|
||||
</div>
|
||||
<div className="grid grid-cols-3 gap-1.5">
|
||||
{f.generated_images.map((g) => (
|
||||
<a
|
||||
key={g.id}
|
||||
href={generatedImageUrl(jobId, f.index, g.id)}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
title={g.prompt}
|
||||
className={`relative aspect-square rounded-md overflow-hidden border-2 transition ${
|
||||
g.selected ? "border-emerald-400 ring-2 ring-emerald-400/40" : "border-white/15 hover:border-white/40"
|
||||
}`}
|
||||
>
|
||||
<img
|
||||
src={generatedImageUrl(jobId, f.index, g.id)}
|
||||
alt={`gen ${g.id}`}
|
||||
className="absolute inset-0 w-full h-full object-cover"
|
||||
/>
|
||||
{g.selected && (
|
||||
<div className="absolute top-1 right-1 bg-emerald-500 text-white rounded-full p-0.5">
|
||||
<Check className="h-2.5 w-2.5" />
|
||||
</div>
|
||||
)}
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user