auto-save 2026-05-21 08:45 (~2)
This commit is contained in:
@@ -1895,6 +1895,13 @@
|
|||||||
"message": "auto-save 2026-05-21 02:30 (~2)",
|
"message": "auto-save 2026-05-21 02:30 (~2)",
|
||||||
"hash": "9520d93",
|
"hash": "9520d93",
|
||||||
"files_changed": 2
|
"files_changed": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-21T02:36:11+08:00",
|
||||||
|
"type": "commit",
|
||||||
|
"message": "auto-save 2026-05-21 02:36 (~2)",
|
||||||
|
"hash": "515ef79",
|
||||||
|
"files_changed": 2
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -427,14 +427,14 @@ function VideoSection({ videoLoading, primaryImage, locked, session, onGenerateV
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="grid grid-cols-1 gap-3 border-t border-white/[0.05] p-4 xl:grid-cols-2">
|
<div className="grid grid-cols-1 gap-2 border-t border-white/[0.05] p-3 2xl:grid-cols-2">
|
||||||
{videoItems.map(item => {
|
{videoItems.map(item => {
|
||||||
const isOpen = showPromptId === item.id;
|
const isOpen = showPromptId === item.id;
|
||||||
const task = byTemplate.get(item.id);
|
const task = byTemplate.get(item.id);
|
||||||
const loadingThis = videoLoading === item.id;
|
const loadingThis = videoLoading === item.id;
|
||||||
return (
|
return (
|
||||||
<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 key={item.id} className="grid min-w-0 grid-cols-[128px_minmax(0,1fr)] gap-3 rounded-[8px] bg-white/[0.025] p-2.5 ring-1 ring-white/[0.05] transition-all hover:ring-white/[0.12]">
|
||||||
<div className="relative bg-black/70" style={{ aspectRatio: item.ratio.replace(':', ' / ') }}>
|
<div className="relative h-24 overflow-hidden rounded-[8px] bg-black/70">
|
||||||
{task?.videoUrl ? (
|
{task?.videoUrl ? (
|
||||||
<HoverVideoPreview
|
<HoverVideoPreview
|
||||||
src={task.videoUrl}
|
src={task.videoUrl}
|
||||||
@@ -449,29 +449,29 @@ function VideoSection({ videoLoading, primaryImage, locked, session, onGenerateV
|
|||||||
<span className="text-[10px] font-mono">{item.duration}s</span>
|
<span className="text-[10px] font-mono">{item.duration}s</span>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<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">
|
<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-1.5">
|
||||||
<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-black/58 px-1.5 py-0.5 text-[8px] 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>
|
<span className="rounded-[6px] bg-[#e6f578]/90 px-1.5 py-0.5 text-[8px] font-bold text-[#081006]">{item.duration}s</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="space-y-2 p-3">
|
<div className="min-w-0 space-y-1">
|
||||||
<div className="flex items-start justify-between gap-3">
|
<div className="flex items-start justify-between gap-2">
|
||||||
<div className="min-w-0">
|
<div className="min-w-0">
|
||||||
<div className="flex items-center gap-1.5 flex-wrap">
|
<div className="flex items-center gap-1.5 flex-wrap">
|
||||||
<span className="text-[13px] font-semibold text-white">{item.title}</span>
|
<span className="text-[12px] font-semibold text-white">{item.title}</span>
|
||||||
{!item.template && <span className="chip chip-live text-[10px] py-0">回填</span>}
|
{!item.template && <span className="chip chip-live text-[10px] py-0">回填</span>}
|
||||||
</div>
|
</div>
|
||||||
<p className="mt-1 line-clamp-2 text-[11px] leading-relaxed text-white/45">{item.description}</p>
|
<p className="mt-1 line-clamp-1 text-[10px] leading-relaxed text-white/42">{item.description}</p>
|
||||||
</div>
|
</div>
|
||||||
<span className={`shrink-0 text-[10px] ${task ? 'text-[#dff5a8]' : 'text-white/25'}`}>
|
<span className={`shrink-0 text-[10px] ${task ? 'text-[#dff5a8]' : 'text-white/25'}`}>
|
||||||
{task?.status ?? '待提交'}
|
{task?.status ?? '待提交'}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
{task && (
|
{task && (
|
||||||
<div className="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/24 px-2 py-1 text-[9px] leading-relaxed text-white/44 ring-1 ring-white/[0.05]">
|
||||||
<div className="flex flex-wrap items-center gap-2">
|
<div className="flex min-w-0 items-center gap-2">
|
||||||
<span className="text-[#dff5a8]">{task.status}</span>
|
<span className="text-[#dff5a8]">{task.status}</span>
|
||||||
{task.taskId && <span className="font-mono text-white/34">{task.taskId}</span>}
|
{task.taskId && <span className="truncate font-mono text-white/30">{task.taskId}</span>}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@@ -491,7 +491,7 @@ function VideoSection({ videoLoading, primaryImage, locked, session, onGenerateV
|
|||||||
<a href={task.videoUrl} target="_blank" rel="noreferrer" className="btn btn-outline px-3 py-1.5 text-[11px]">
|
<a href={task.videoUrl} target="_blank" rel="noreferrer" className="btn btn-outline px-3 py-1.5 text-[11px]">
|
||||||
打开
|
打开
|
||||||
</a>
|
</a>
|
||||||
<a href={task.videoUrl} download={`${session.id}_${item.id}.mp4`} className="btn btn-outline px-3 py-1.5 text-[11px]">
|
<a href={task.videoUrl} download={`${session.id}_${item.id}.mp4`} className="btn btn-outline px-2.5 py-1.5 text-[11px]">
|
||||||
下载
|
下载
|
||||||
</a>
|
</a>
|
||||||
</>
|
</>
|
||||||
@@ -499,7 +499,7 @@ function VideoSection({ videoLoading, primaryImage, locked, session, onGenerateV
|
|||||||
<button
|
<button
|
||||||
onClick={() => task?.taskId ? onRefreshVideo(task.taskId) : item.template ? onGenerateVideo(primaryImage, item.template) : undefined}
|
onClick={() => task?.taskId ? onRefreshVideo(task.taskId) : item.template ? onGenerateVideo(primaryImage, item.template) : undefined}
|
||||||
disabled={Boolean(videoLoading) || locked || task?.status === 'succeeded' || (!item.template && !task?.taskId)}
|
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"
|
className="btn btn-primary px-2.5 py-1.5 text-[11px] disabled:opacity-40"
|
||||||
title={locked ? '四个图片包完成后解锁视频任务' : undefined}
|
title={locked ? '四个图片包完成后解锁视频任务' : undefined}
|
||||||
>
|
>
|
||||||
{locked ? '锁定' : loadingThis ? '...' : task ? task.status === 'succeeded' ? '完成' : '刷新' : '提交'}
|
{locked ? '锁定' : loadingThis ? '...' : task ? task.status === 'succeeded' ? '完成' : '刷新' : '提交'}
|
||||||
|
|||||||
Reference in New Issue
Block a user