auto-save 2026-05-13 11:56 (~4)
This commit is contained in:
@@ -1383,6 +1383,13 @@
|
||||
"type": "session-heartbeat",
|
||||
"message": "Claude 会话活跃 · 最近命令:claude · 2 项未提交变更 · 最近提交:auto-save 2026-05-13 11:45 (~4)",
|
||||
"files_changed": 2
|
||||
},
|
||||
{
|
||||
"ts": "2026-05-13T11:51:07+08:00",
|
||||
"type": "commit",
|
||||
"message": "auto-save 2026-05-13 11:50 (~2)",
|
||||
"hash": "4135465",
|
||||
"files_changed": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import { createPortal } from "react-dom"
|
||||
import {
|
||||
Link2, Upload, Download, Scissors, Image as ImageIcon,
|
||||
Mic, Languages, FileEdit, Sparkles, Film, FileVideo, Loader2, Plus, Check,
|
||||
ChevronDown, X,
|
||||
ChevronDown, X, LayoutGrid,
|
||||
} from "lucide-react"
|
||||
import { type Job, type KeyFrame, frameUrl, effectiveFrameUrl, videoUrl, generateImage, selectGenerated, generatedImageUrl } from "@/lib/api"
|
||||
import { type NodeData } from "@/components/nodes"
|
||||
@@ -179,7 +179,7 @@ export const Dashboard = forwardRef<DashboardHandle, Props>(function Dashboard({
|
||||
asr: hasTranscript ? `${job!.transcript.length} 段` : "—",
|
||||
translate: hasZh ? `${job!.transcript.filter((s) => s.zh).length} 段` : "—",
|
||||
rewrite: "占位",
|
||||
imagegen: data.selectedFrames.size > 0 ? `${data.selectedFrames.size} 张待生` : "占位",
|
||||
imagegen: data.selectedFrames.size > 0 ? `${data.selectedFrames.size} 帧待编排` : "占位",
|
||||
videogen: "占位",
|
||||
compose: "占位",
|
||||
}
|
||||
@@ -190,7 +190,7 @@ export const Dashboard = forwardRef<DashboardHandle, Props>(function Dashboard({
|
||||
{ key: "asr", title: "转录", type: "ai", icon: <Mic className="h-3.5 w-3.5" />, step: 3 },
|
||||
{ key: "translate", title: "翻译", type: "ai", icon: <Languages className="h-3.5 w-3.5" />, step: 4 },
|
||||
{ key: "rewrite", title: "改写", type: "ai", icon: <FileEdit className="h-3.5 w-3.5" />, step: 5 },
|
||||
{ key: "imagegen", title: "生图", type: "ai", icon: <Sparkles className="h-3.5 w-3.5" />, step: 6 },
|
||||
{ key: "imagegen", title: "分镜头编排", type: "ai", icon: <LayoutGrid className="h-3.5 w-3.5" />, step: 6 },
|
||||
{ key: "videogen", title: "生视频", type: "ai", icon: <Film className="h-3.5 w-3.5" />, step: 7 },
|
||||
{ key: "compose", title: "合成", type: "output", icon: <FileVideo className="h-3.5 w-3.5" />, step: 8 },
|
||||
]
|
||||
@@ -249,7 +249,7 @@ export const Dashboard = forwardRef<DashboardHandle, Props>(function Dashboard({
|
||||
<div className="h-full flex flex-col gap-1 px-1.5 py-2">
|
||||
{/* 起点:输入(含下载+拆分) */}
|
||||
<Tile tkey="input" />
|
||||
{/* 分叉:上路 关键帧/生图/生视频 */}
|
||||
{/* 分叉:上路 关键帧/分镜头编排/生视频 */}
|
||||
<div className="border-l border-violet-400/25 pl-1 ml-[3px] space-y-1">
|
||||
<Tile tkey="keyframe" />
|
||||
<Tile tkey="imagegen" />
|
||||
@@ -603,7 +603,7 @@ export const Dashboard = forwardRef<DashboardHandle, Props>(function Dashboard({
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* ---- ImageGen — 选中关键帧每张一卡,生成 + 多版本 ---- */}
|
||||
{/* ---- 分镜头编排 — 基于关键帧 + 元素 + 场景图编排(Phase 2 重写) ---- */}
|
||||
{key === "imagegen" && (
|
||||
data.selectedFrames.size === 0 ? (
|
||||
<KanbanCard tone="pink" tags={["待启动"]} title="未选关键帧">
|
||||
|
||||
@@ -454,7 +454,7 @@ export function FrameLightbox({ jobId, frames, activeIndex, selected, onClose, o
|
||||
onClick={handleApplyCleaned}
|
||||
disabled={applying}
|
||||
className="w-full px-2 py-1.5 rounded-md text-[11px] font-medium inline-flex items-center justify-center gap-1 transition bg-emerald-500 hover:bg-emerald-400 text-white disabled:opacity-40 disabled:cursor-not-allowed"
|
||||
title="替换原图为这张干净版 · 后续抠图 / 生图都基于干净版"
|
||||
title="替换原图为这张干净版 · 后续抠图 / 分镜头编排都基于干净版"
|
||||
>
|
||||
{applying ? <Loader2 className="h-3 w-3 animate-spin" /> : <Check className="h-3 w-3" />}
|
||||
{applying ? "替换中…" : "✓ 替换原图"}
|
||||
|
||||
@@ -3,7 +3,7 @@ import { useRef, useState } from "react"
|
||||
import { type NodeProps } from "@xyflow/react"
|
||||
import {
|
||||
Link2, Upload, Download, Scissors, Image as ImageIcon,
|
||||
Mic, Languages, FileEdit, Sparkles, Film, FileVideo, Loader2, Plus, X,
|
||||
Mic, Languages, FileEdit, Sparkles, Film, FileVideo, Loader2, Plus, X, LayoutGrid,
|
||||
} from "lucide-react"
|
||||
import { NodeShell, type NodeStatus, type NodeKind } from "./node-shell"
|
||||
import { type Job, frameUrl, effectiveFrameUrl, videoUrl, generatedImageUrl } from "@/lib/api"
|
||||
@@ -403,7 +403,7 @@ export function KeyframeNode({ data, selected }: any) {
|
||||
{f.timestamp.toFixed(1)}s
|
||||
</div>
|
||||
|
||||
{/* Hover 静态大图预览(关键帧是给下游生图垫图的素材,不需要视频) */}
|
||||
{/* Hover 静态大图预览(关键帧素材给下游分镜头编排用) */}
|
||||
<div
|
||||
className="pointer-events-none absolute opacity-0 group-hover:opacity-100 scale-95 group-hover:scale-100 transition-all duration-200 z-[60]"
|
||||
style={{
|
||||
@@ -627,7 +627,7 @@ export function ImageGenNode({ data, selected }: any) {
|
||||
>
|
||||
<button
|
||||
onClick={(e) => { e.stopPropagation(); d.onOpenPanel?.("imagegen") }}
|
||||
title={`分镜 ${p.frameIdx + 1} · ${p.total} 张${p.hasSelected ? " · 已选用" : ""} · 打开「生图」面板`}
|
||||
title={`分镜 ${p.frameIdx + 1} · ${p.total} 张${p.hasSelected ? " · 已选用" : ""} · 打开「分镜头编排」`}
|
||||
className="absolute inset-0 w-full h-full"
|
||||
>
|
||||
<img
|
||||
@@ -696,9 +696,9 @@ export function ImageGenNode({ data, selected }: any) {
|
||||
|
||||
<NodeShell
|
||||
type="ai" status={status}
|
||||
icon={<Sparkles className="h-4 w-4" />}
|
||||
title="生图 · Image Gen"
|
||||
subtitle={`STEP 6 · nano-banana ${totalGens > 0 ? `· ${totalGens} 张` : ""}`}
|
||||
icon={<LayoutGrid className="h-4 w-4" />}
|
||||
title="分镜头编排 · Storyboard"
|
||||
subtitle={`STEP 6 · 接元素 + 场景 ${totalGens > 0 ? `· ${totalGens} 张` : ""}`}
|
||||
width={IMAGEGEN_WIDTH}
|
||||
selected={selected}
|
||||
>
|
||||
@@ -707,17 +707,14 @@ export function ImageGenNode({ data, selected }: any) {
|
||||
已生成 <span className="text-[var(--text-strong)] font-medium">{totalGens}</span> 张 · 选用 {selectedCount}/{previews.length}
|
||||
<br />
|
||||
<span className="text-[10.5px] text-[var(--text-faint)]">
|
||||
上方缩略图点击展开分镜 · 在 sidebar「生图」节点调参再生成
|
||||
上方缩略图点击展开编排 · 多视角 / 风格融合 / 布局调整在此完成
|
||||
</span>
|
||||
</div>
|
||||
) : (
|
||||
<div className="grid grid-cols-2 gap-1.5">
|
||||
<div className="rounded-md border border-dashed border-black/15 dark:border-white/10 px-2 py-1.5 text-[10.5px] text-[var(--text-faint)]">
|
||||
nano-banana-pro<br /><span className="text-[var(--text-strong)] text-[11px]">Gemini 3 Image</span>
|
||||
</div>
|
||||
<div className="rounded-md border border-dashed border-black/15 dark:border-white/10 px-2 py-1.5 text-[10.5px] text-[var(--text-faint)]">
|
||||
GPT Image<br /><span className="text-[var(--text-strong)] text-[11px]">OpenAI</span>
|
||||
</div>
|
||||
<div className="text-[11.5px] text-[var(--text-faint)] leading-relaxed">
|
||||
<span className="text-[var(--text-strong)]">编排素材待接入</span>
|
||||
<br />
|
||||
<span className="text-[10.5px]">关键帧节点提取的元素 + 干净版场景图 → 这里做多视角 / 风格融合 / 分镜布局</span>
|
||||
</div>
|
||||
)}
|
||||
</NodeShell>
|
||||
|
||||
Reference in New Issue
Block a user