auto-save 2026-05-21 02:25 (~2)
This commit is contained in:
@@ -1874,6 +1874,13 @@
|
||||
"message": "auto-save 2026-05-21 02:09 (~5)",
|
||||
"hash": "fa6e32b",
|
||||
"files_changed": 5
|
||||
},
|
||||
{
|
||||
"ts": "2026-05-21T02:19:55+08:00",
|
||||
"type": "commit",
|
||||
"message": "auto-save 2026-05-21 02:19 (~2)",
|
||||
"hash": "da12ed0",
|
||||
"files_changed": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -427,54 +427,55 @@ function VideoSection({ videoLoading, primaryImage, locked, session, onGenerateV
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="px-4 pb-4 border-t border-white/[0.05] space-y-2 pt-3">
|
||||
<div className="grid grid-cols-1 gap-3 border-t border-white/[0.05] p-4 xl:grid-cols-2">
|
||||
{videoItems.map(item => {
|
||||
const isOpen = showPromptId === item.id;
|
||||
const task = byTemplate.get(item.id);
|
||||
const loadingThis = videoLoading === item.id;
|
||||
return (
|
||||
<div key={item.id} className="grid grid-cols-[72px_minmax(0,1fr)_auto] gap-3 p-3 rounded-[8px] bg-white/[0.025] ring-1 ring-white/[0.05] hover:ring-white/[0.1] transition-all">
|
||||
<div className="aspect-square rounded-[8px] bg-gradient-to-br from-[#e6f578]/15 to-[#8cb478]/15 ring-1 ring-[#e6f578]/20 flex flex-col items-center justify-center text-[#e6f578] text-[9px] font-mono gap-1">
|
||||
<div key={item.id} className="min-w-0 overflow-hidden rounded-[8px] bg-white/[0.025] ring-1 ring-white/[0.05] transition-all hover:ring-white/[0.12]">
|
||||
<div className="relative bg-black/70" style={{ aspectRatio: item.ratio.replace(':', ' / ') }}>
|
||||
{task?.videoUrl ? (
|
||||
<div className="relative h-full w-full overflow-hidden rounded-[8px] bg-black">
|
||||
<HoverVideoPreview
|
||||
src={task.videoUrl}
|
||||
aspectRatio={item.ratio}
|
||||
className="h-full w-full object-contain"
|
||||
/>
|
||||
<span className="pointer-events-none absolute bottom-1 left-1 rounded-[6px] bg-black/70 px-1.5 py-0.5 text-[8px] font-semibold text-[#e6f578]">
|
||||
{item.duration}s
|
||||
</span>
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<div className="flex h-full w-full flex-col items-center justify-center gap-1 bg-gradient-to-br from-[#e6f578]/12 to-[#8cb478]/12 text-[#e6f578]">
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
|
||||
<path d="M8 5.2v13.6L18.5 12 8 5.2z" />
|
||||
</svg>
|
||||
<span className="text-[8px]">{item.duration}s</span>
|
||||
</>
|
||||
)}
|
||||
<span className="text-[10px] font-mono">{item.duration}s</span>
|
||||
</div>
|
||||
<div className="min-w-0 space-y-1">
|
||||
)}
|
||||
<div className="pointer-events-none absolute inset-x-0 bottom-0 flex items-center justify-between bg-gradient-to-t from-black/82 to-transparent p-2">
|
||||
<span className="rounded-[6px] bg-black/58 px-2 py-0.5 text-[9px] font-semibold text-white/72">{item.ratio}</span>
|
||||
<span className="rounded-[6px] bg-[#e6f578]/90 px-2 py-0.5 text-[9px] font-bold text-[#081006]">{item.duration}s</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-2 p-3">
|
||||
<div className="flex items-start justify-between gap-3">
|
||||
<div className="min-w-0">
|
||||
<div className="flex items-center gap-1.5 flex-wrap">
|
||||
<span className="text-[13px] font-medium text-white">{item.title}</span>
|
||||
<span className="chip chip-neutral text-[10px] py-0">{item.ratio}</span>
|
||||
<span className="text-[13px] font-semibold text-white">{item.title}</span>
|
||||
{!item.template && <span className="chip chip-live text-[10px] py-0">回填</span>}
|
||||
</div>
|
||||
<p className="text-[11px] text-white/45 line-clamp-1">{item.description}</p>
|
||||
<p className="mt-1 line-clamp-2 text-[11px] leading-relaxed text-white/45">{item.description}</p>
|
||||
</div>
|
||||
<span className={`shrink-0 text-[10px] ${task ? 'text-[#dff5a8]' : 'text-white/25'}`}>
|
||||
{task?.status ?? '待提交'}
|
||||
</span>
|
||||
</div>
|
||||
{task && (
|
||||
<div className="mt-2 rounded-lg bg-black/28 p-2 text-[10px] leading-relaxed text-white/48 ring-1 ring-white/[0.06]">
|
||||
<div className="rounded-lg bg-black/28 p-2 text-[10px] leading-relaxed text-white/48 ring-1 ring-white/[0.06]">
|
||||
<div className="flex flex-wrap items-center gap-2">
|
||||
<span className="text-[#dff5a8]">{task.status}</span>
|
||||
{task.taskId && <span className="font-mono text-white/34">{task.taskId}</span>}
|
||||
{task.videoUrl && (
|
||||
<a href={task.videoUrl} target="_blank" rel="noreferrer" className="text-[#e6f578] hover:text-white">
|
||||
打开视频
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className="flex flex-wrap items-center justify-between gap-2">
|
||||
<button
|
||||
onClick={() => setShowPromptId(isOpen ? null : item.id)}
|
||||
className="text-[10px] text-white/30 hover:text-[#e6f578] transition-colors flex items-center gap-1"
|
||||
@@ -484,20 +485,33 @@ function VideoSection({ videoLoading, primaryImage, locked, session, onGenerateV
|
||||
</svg>
|
||||
Prompt
|
||||
</button>
|
||||
<div className="flex items-center gap-2">
|
||||
{task?.videoUrl && (
|
||||
<>
|
||||
<a href={task.videoUrl} target="_blank" rel="noreferrer" className="btn btn-outline px-3 py-1.5 text-[11px]">
|
||||
打开
|
||||
</a>
|
||||
<a href={task.videoUrl} download={`${session.id}_${item.id}.mp4`} className="btn btn-outline px-3 py-1.5 text-[11px]">
|
||||
下载
|
||||
</a>
|
||||
</>
|
||||
)}
|
||||
<button
|
||||
onClick={() => task?.taskId ? onRefreshVideo(task.taskId) : item.template ? onGenerateVideo(primaryImage, item.template) : undefined}
|
||||
disabled={Boolean(videoLoading) || locked || task?.status === 'succeeded' || (!item.template && !task?.taskId)}
|
||||
className="btn btn-primary text-[11px] px-3 py-1.5 disabled:opacity-40"
|
||||
title={locked ? '四个图片包完成后解锁视频任务' : undefined}
|
||||
>
|
||||
{locked ? '锁定' : loadingThis ? '...' : task ? task.status === 'succeeded' ? '完成' : '刷新' : '提交'}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{isOpen && (
|
||||
<pre className="p-2 text-[10px] text-white/60 bg-black/40 rounded-lg ring-1 ring-white/[0.07] font-mono whitespace-pre-wrap break-all max-h-28 overflow-y-auto">
|
||||
{item.promptTemplate}
|
||||
</pre>
|
||||
)}
|
||||
</div>
|
||||
<button
|
||||
onClick={() => task?.taskId ? onRefreshVideo(task.taskId) : item.template ? onGenerateVideo(primaryImage, item.template) : undefined}
|
||||
disabled={Boolean(videoLoading) || locked || task?.status === 'succeeded' || (!item.template && !task?.taskId)}
|
||||
className="self-center btn btn-primary text-[11px] px-3 py-1.5 disabled:opacity-40"
|
||||
title={locked ? '四个图片包完成后解锁视频任务' : undefined}
|
||||
>
|
||||
{locked ? '锁定' : loadingThis ? '...' : task ? task.status === 'succeeded' ? '完成' : '刷新' : '提交'}
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
|
||||
Reference in New Issue
Block a user