auto-save 2026-05-13 11:50 (~2)

This commit is contained in:
2026-05-13 11:51:07 +08:00
parent 5328965e20
commit 4135465bb2
2 changed files with 73 additions and 3 deletions

View File

@@ -1370,6 +1370,19 @@
"message": "auto-save 2026-05-13 11:39 (~1)",
"hash": "9214885",
"files_changed": 1
},
{
"ts": "2026-05-13T11:45:33+08:00",
"type": "commit",
"message": "auto-save 2026-05-13 11:45 (~4)",
"hash": "5328965",
"files_changed": 4
},
{
"ts": "2026-05-13T03:47:37Z",
"type": "session-heartbeat",
"message": "Claude 会话活跃 · 最近命令claude · 2 项未提交变更 · 最近提交auto-save 2026-05-13 11:45 (~4)",
"files_changed": 2
}
]
}

View File

@@ -92,6 +92,54 @@ export const Dashboard = forwardRef<DashboardHandle, Props>(function Dashboard({
useImperativeHandle(ref, () => ({
openPanel: (key: string) => setExpanded(new Set([key])),
}), [])
// drawer 宽度 per panel · 持久化到 localStorage
const drawerKey = (() => {
const keys = Array.from(expanded)
if (keys.length === 0) return ""
const base = keys[0]
if (base === "keyframe" && data.expandedFrame !== null) return "keyframe:lightbox"
return base
})()
const defaultWidth = drawerKey === "keyframe:lightbox" ? 760 : 400
const [drawerWidths, setDrawerWidths] = useState<Record<string, number>>({})
useEffect(() => {
if (typeof window === "undefined") return
try {
const stored = JSON.parse(localStorage.getItem("skg.drawer.widths") || "{}")
if (stored && typeof stored === "object") setDrawerWidths(stored)
} catch { /* ignore */ }
}, [])
const drawerWidth = drawerKey ? (drawerWidths[drawerKey] ?? defaultWidth) : defaultWidth
const setDrawerWidth = (w: number) => {
if (!drawerKey) return
const clamped = Math.max(280, Math.min(1400, w))
setDrawerWidths((prev) => {
const next = { ...prev, [drawerKey]: clamped }
try { localStorage.setItem("skg.drawer.widths", JSON.stringify(next)) } catch { /* ignore */ }
return next
})
}
// 拖拽
const dragRef = useRef<{ startX: number; startW: number } | null>(null)
const onResizeMouseDown = (e: React.MouseEvent) => {
e.preventDefault()
e.stopPropagation()
dragRef.current = { startX: e.clientX, startW: drawerWidth }
const onMove = (ev: MouseEvent) => {
if (!dragRef.current) return
const delta = ev.clientX - dragRef.current.startX
setDrawerWidth(dragRef.current.startW + delta)
}
const onUp = () => {
dragRef.current = null
window.removeEventListener("mousemove", onMove)
window.removeEventListener("mouseup", onUp)
}
window.addEventListener("mousemove", onMove)
window.addEventListener("mouseup", onUp)
}
const tileRefs = useRef<Record<string, HTMLButtonElement | null>>({})
const fileRef = useRef<HTMLInputElement>(null)
const videoRef = useRef<HTMLVideoElement>(null)
@@ -216,7 +264,7 @@ export const Dashboard = forwardRef<DashboardHandle, Props>(function Dashboard({
{/* 合流 */}
<Tile tkey="compose" />
{/* 展开面板 — keyframe 有选中帧时变宽容纳 lightbox */}
{/* 展开面板 — keyframe 有选中帧时变宽容纳 lightbox · 可拖拽改宽 */}
{expanded.size > 0 && mounted && createPortal(
<div
className="fixed z-[100]"
@@ -224,7 +272,7 @@ export const Dashboard = forwardRef<DashboardHandle, Props>(function Dashboard({
left: 104,
top: 16,
bottom: 16,
width: expanded.has("keyframe") && data.expandedFrame !== null ? 760 : 400,
width: drawerWidth,
}}
>
{TILES.filter((t) => expanded.has(t.key)).map((t) => {
@@ -232,12 +280,21 @@ export const Dashboard = forwardRef<DashboardHandle, Props>(function Dashboard({
return (
<section
key={t.key}
className="rounded-2xl border border-white/15 bg-black/60 backdrop-blur-2xl overflow-hidden flex flex-col h-full"
className="rounded-2xl border border-white/15 bg-black/60 backdrop-blur-2xl overflow-hidden flex flex-col h-full relative"
style={{
animation: "drawer-in 0.24s cubic-bezier(0.32, 0.72, 0, 1)",
boxShadow: "0 30px 80px -20px rgba(0,0,0,0.7), 0 0 0 1px rgba(255,255,255,0.05)",
}}
>
{/* 右边拖拽手柄 — hover 时显示 */}
<div
onMouseDown={onResizeMouseDown}
title="拖动改变宽度(双击重置)"
onDoubleClick={() => setDrawerWidth(defaultWidth)}
className="group/rs absolute top-0 bottom-0 right-0 w-1.5 cursor-col-resize hover:bg-violet-400/30 transition z-[110]"
>
<div className="absolute top-1/2 -translate-y-1/2 right-0 w-1 h-12 bg-white/0 group-hover/rs:bg-violet-400/70 rounded-l transition" />
</div>
<div className="flex items-center justify-between px-3 py-2" style={{ background: TYPE_GRAD[t.type] }}>
<div className="flex items-center gap-1.5">
<span className="text-white/70 text-[9px] font-mono">{String(t.step).padStart(2, "0")}</span>