auto-save 2026-05-13 11:50 (~2)
This commit is contained in:
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user