auto-save 2026-05-14 00:25 (+6, ~5)

This commit is contained in:
2026-05-14 00:26:10 +08:00
parent 540107d505
commit abeff424f6
11 changed files with 1262 additions and 57 deletions

View File

@@ -50,12 +50,14 @@ const LAYOUT: Array<{ id: string; type: keyof typeof NODE_TYPES; x: number; y: n
{ id: "compose", type: "compose", x: 1640, y: 240, w: 320 },
]
const NODE_WIDTHS_KEY = "skg-tk:node-widths:v1"
const NODE_SIZES_KEY = "skg-tk:node-sizes:v2"
function loadNodeWidths(): Record<string, number> {
type NodeSize = { w?: number; h?: number }
function loadNodeSizes(): Record<string, NodeSize> {
if (typeof window === "undefined") return {}
try {
const raw = window.localStorage.getItem(NODE_WIDTHS_KEY)
const raw = window.localStorage.getItem(NODE_SIZES_KEY)
return raw ? JSON.parse(raw) : {}
} catch {
return {}
@@ -445,27 +447,36 @@ export default function Home() {
}), [job, jobs, activeJobId, submitting, analyzing, selectedFrames, expandedFrame, framePanelScale, framePanelPinned, handleSubmit, handleUpload, handleAnalyze, handleToggleFrame, handleOpenFramePanel, handleFramePanelScaleChange, handleAddManualFrame, handleSwitchJob, setJob, handleDeleteFrame, handleDeleteGenerated, handleDeleteVideo, handleCopyImage])
// 用 useNodesState 让 ReactFlow 自己管位置(避免轮询时重置 drag
const savedWidths = useMemo(() => loadNodeWidths(), [])
const savedSizes = useMemo(() => loadNodeSizes(), [])
const [nodes, setNodes, onNodesChange] = useNodesState<Node>(
LAYOUT.map((n) => ({
id: n.id,
type: n.type,
position: { x: n.x, y: n.y },
data: nodeData,
draggable: true,
width: savedWidths[n.id] ?? n.w,
})),
LAYOUT.map((n) => {
const s = savedSizes[n.id] ?? {}
const w = s.w ?? n.w
const h = s.h
return {
id: n.id,
type: n.type,
position: { x: n.x, y: n.y },
data: nodeData,
draggable: true,
width: w,
...(typeof h === "number" ? { height: h } : {}),
style: { width: w, ...(typeof h === "number" ? { height: h } : {}) },
}
}),
)
// 持久化每个节点宽到 localStorageKeyframePanelNode 自己管尺寸,不写回)
// 持久化每个节点宽 / 高到 localStorageKeyframePanelNode 自己管尺寸,不写回)
useEffect(() => {
const widths: Record<string, number> = {}
const sizes: Record<string, NodeSize> = {}
for (const n of nodes) {
if (n.id === KEYFRAME_PANEL_ID) continue
const w = n.width
if (typeof w === "number") widths[n.id] = Math.round(w)
const w = typeof n.width === "number" ? Math.round(n.width) : undefined
const h = typeof n.height === "number" ? Math.round(n.height) : undefined
if (w === undefined && h === undefined) continue
sizes[n.id] = { ...(w !== undefined ? { w } : {}), ...(h !== undefined ? { h } : {}) }
}
try { window.localStorage.setItem(NODE_WIDTHS_KEY, JSON.stringify(widths)) } catch {}
try { window.localStorage.setItem(NODE_SIZES_KEY, JSON.stringify(sizes)) } catch {}
}, [nodes])
const [edges, setEdges, onEdgesChange] = useEdgesState<Edge>(
EDGES_RAW.map(([from, to], i) => ({