auto-save 2026-05-14 00:48 (+4, ~3)

This commit is contained in:
2026-05-14 00:48:59 +08:00
parent 042efdc376
commit e8a653e524
7 changed files with 673 additions and 4 deletions

View File

@@ -64,6 +64,18 @@ function loadNodeSizes(): Record<string, NodeSize> {
}
}
const NODE_PINS_KEY = "skg-tk:node-pins:v1"
function loadNodePins(): string[] {
if (typeof window === "undefined") return []
try {
const raw = window.localStorage.getItem(NODE_PINS_KEY)
return raw ? JSON.parse(raw) : []
} catch {
return []
}
}
const EDGES_RAW: Array<[string, string]> = [
["input", "keyframe"],
["input", "asr"],
@@ -412,6 +424,16 @@ export default function Home() {
return () => { if (pollRef.current) clearInterval(pollRef.current) }
}, [job?.id, job?.status, job?.generated_videos?.map((v) => `${v.id}:${v.status}:${v.progress}`).join("|")])
const [pinnedNodes, setPinnedNodes] = useState<Set<string>>(() => new Set(loadNodePins()))
const handleToggleNodePin = useCallback((id: string) => {
setPinnedNodes((prev) => {
const next = new Set(prev)
if (next.has(id)) next.delete(id); else next.add(id)
try { window.localStorage.setItem(NODE_PINS_KEY, JSON.stringify([...next])) } catch {}
return next
})
}, [])
const nodeData: NodeData = useMemo(() => ({
job,
jobs,
@@ -444,7 +466,9 @@ export default function Home() {
setWorkbenchOpen(true)
},
onCopyImage: handleCopyImage,
}), [job, jobs, activeJobId, submitting, analyzing, selectedFrames, expandedFrame, framePanelScale, framePanelPinned, handleSubmit, handleUpload, handleAnalyze, handleToggleFrame, handleOpenFramePanel, handleFramePanelScaleChange, handleAddManualFrame, handleSwitchJob, setJob, handleDeleteFrame, handleDeleteGenerated, handleDeleteVideo, handleCopyImage])
pinnedNodes,
onToggleNodePin: handleToggleNodePin,
}), [job, jobs, activeJobId, submitting, analyzing, selectedFrames, expandedFrame, framePanelScale, framePanelPinned, handleSubmit, handleUpload, handleAnalyze, handleToggleFrame, handleOpenFramePanel, handleFramePanelScaleChange, handleAddManualFrame, handleSwitchJob, setJob, handleDeleteFrame, handleDeleteGenerated, handleDeleteVideo, handleCopyImage, pinnedNodes, handleToggleNodePin])
// 用 useNodesState 让 ReactFlow 自己管位置(避免轮询时重置 drag
const savedSizes = useMemo(() => loadNodeSizes(), [])
@@ -453,12 +477,13 @@ export default function Home() {
const s = savedSizes[n.id] ?? {}
const w = s.w ?? n.w
const h = s.h
const isPinned = pinnedNodes.has(n.id)
return {
id: n.id,
type: n.type,
position: { x: n.x, y: n.y },
data: nodeData,
draggable: true,
draggable: !isPinned,
width: w,
...(typeof h === "number" ? { height: h } : {}),
style: { width: w, ...(typeof h === "number" ? { height: h } : {}) },
@@ -466,6 +491,13 @@ export default function Home() {
}),
)
// pinned 变化时同步每个节点 draggable
useEffect(() => {
setNodes((prev) => prev.map((n) =>
n.id === KEYFRAME_PANEL_ID ? n : { ...n, draggable: !pinnedNodes.has(n.id) },
))
}, [pinnedNodes, setNodes])
// 持久化每个节点宽 / 高到 localStorageKeyframePanelNode 自己管尺寸,不写回)
useEffect(() => {
const sizes: Record<string, NodeSize> = {}