From 521c1427430de6746cadfa75c7fd1de4b0a7e4a7 Mon Sep 17 00:00:00 2001 From: kang Date: Thu, 14 May 2026 09:25:05 +0800 Subject: [PATCH] auto-save 2026-05-14 09:24 (~2) --- .memory/worklog.json | 27 ++- web/components/lightbox.tsx | 380 +++++++++++++++++++++++------------- 2 files changed, 254 insertions(+), 153 deletions(-) diff --git a/.memory/worklog.json b/.memory/worklog.json index 0a1a3b0..9b053fb 100644 --- a/.memory/worklog.json +++ b/.memory/worklog.json @@ -1,19 +1,5 @@ { "entries": [ - { - "files_changed": 1, - "hash": "8e3b365", - "message": "auto-save 2026-05-12 22:36 (~1)", - "ts": "2026-05-12T22:36:36+08:00", - "type": "commit" - }, - { - "files_changed": 1, - "hash": "2009c43", - "message": "auto-save 2026-05-12 22:41 (~1)", - "ts": "2026-05-12T22:42:07+08:00", - "type": "commit" - }, { "files_changed": 1, "hash": "9279e55", @@ -3331,6 +3317,19 @@ "type": "session-heartbeat", "message": "Codex 会话活跃 · 最近命令:codex · 1 项未提交变更 · 最近提交:auto-save 2026-05-14 09:13 (~1)", "files_changed": 1 + }, + { + "ts": "2026-05-14T09:19:35+08:00", + "type": "commit", + "message": "auto-save 2026-05-14 09:19 (~2)", + "hash": "1ac55e5", + "files_changed": 2 + }, + { + "ts": "2026-05-14T01:20:31Z", + "type": "session-heartbeat", + "message": "Claude 会话活跃 · 最近命令:claude · 1 项未提交变更 · 最近提交:auto-save 2026-05-14 09:19 (~2)", + "files_changed": 1 } ] } diff --git a/web/components/lightbox.tsx b/web/components/lightbox.tsx index d6efb3f..fd3de51 100644 --- a/web/components/lightbox.tsx +++ b/web/components/lightbox.tsx @@ -696,7 +696,7 @@ export function FrameLightbox({ jobId, frames, activeIndex, selected, onClose, o } : { top: 80, right: 16, - width: 740, + width: isProductTab ? "min(1280px, calc(100vw - 32px))" : 740, maxHeight: "calc(100vh - 96px)", boxShadow: "0 40px 100px -20px rgba(0,0,0,0.7), 0 0 0 1px rgba(255,255,255,0.05)", animation: "drawer-in 0.24s cubic-bezier(0.32, 0.72, 0, 1)", @@ -930,118 +930,237 @@ export function FrameLightbox({ jobId, frames, activeIndex, selected, onClose, o
- 每行一条镜头:产品图、白底人物图、人物图上的产品区域、场景图和描述词一一对应。 + 6 条视频镜头从上到下排列;每条都能直接看到产品图、白底人物、融合区域、场景、描述和秒数。
-
+
{fusionShots.map((shot, i) => { const active = i === activeFusionShot + const productUrl = shot.product_image ? resolveImageRefUrl(jobId, shot.product_image) : "" + const personUrl = shot.person_image ? resolveImageRefUrl(jobId, shot.person_image) : "" + const sceneUrl = shot.scene_image ? resolveImageRefUrl(jobId, shot.scene_image) : "" const ready = !!(shot.product_image && shot.person_image && shot.product_region && shot.scene_image && shot.action_text?.trim()) + const busy = fusionGenerating === i || fusionGenerating === "all" + const pasteIntoSlot = (slot: "product_image" | "person_image" | "scene_image", label: string) => { + setActiveFusionShot(i) + if (clipboard) { + assignFusionImage(slot, clipboard, i) + toast.success(`已粘贴到镜头 ${i + 1}「${label}」:${clipboard.label || "剪贴板图片"}`) + return + } + setFusionUploadTarget(slot) + toast.message(`镜头 ${i + 1} 已选中「${label}」槽位,现在可 Cmd+V 粘贴系统图片`) + } + const imageSlot = (slot: "product_image" | "scene_image", label: string, url: string) => { + const ref = shot[slot] + return ( +
+
+ {url ? ( + + ) : ( + + )} +
+
+
{ref?.label || label}
+
+ + +
+
+
+ ) + } return ( - - ) - })} -
-
- {([ - ["product_image", "产品图", currentFusionProductUrl], - ["person_image", "白底人物图", currentFusionPersonUrl], - ["scene_image", "场景图", currentFusionSceneUrl], - ] as const).map(([slot, label, url]) => ( -
-
- {url ? ( - {label} - ) : ( - - )} -
-
- {label} -
- - +
+
+ + + {ready ? "就绪" : "待补"} + +
+ + {imageSlot("product_image", "产品图", productUrl)} + +
+
{ + setActiveFusionShot(i) + if (active) onFusionRegionDown(ev) + } : undefined} + onMouseMove={active ? onFusionRegionMove : undefined} + onMouseUp={active ? onFusionRegionUp : undefined} + onMouseLeave={active ? onFusionRegionUp : undefined} + className={`relative aspect-[4/5] bg-white ${ + personUrl ? (active ? "cursor-crosshair" : "cursor-pointer") : "" + }`} + title={personUrl ? (active ? "拖动画出产品融合区域" : "点击后编辑此镜头区域") : "上传白底人物图"} + > + {personUrl ? ( + <> + 白底人物图 + {!active && ( +
+ 点此编辑区域 +
+ )} + + ) : ( + + )} + {[shot.product_region, active ? fusionDraftRegion : null].filter(Boolean).map((region, regionIdx) => region && ( +
+ ))} +
+
+
+ {shot.person_image?.label || (shot.product_region ? "人物图 · 已画区域" : "白底人物图")} +
+
+ + +
+
+
+ + {imageSlot("scene_image", "场景图", sceneUrl)} + +