auto-save 2026-05-12 18:57 (~2)

This commit is contained in:
2026-05-12 18:57:53 +08:00
parent f6f821262b
commit 684930d085
2 changed files with 31 additions and 9 deletions

View File

@@ -202,6 +202,13 @@
"message": "auto-save 2026-05-12 18:46 (~3)",
"hash": "5a914b9",
"files_changed": 3
},
{
"ts": "2026-05-12T18:52:21+08:00",
"type": "commit",
"message": "auto-save 2026-05-12 18:52 (~2)",
"hash": "f6f8212",
"files_changed": 2
}
]
}

View File

@@ -80,6 +80,8 @@ export function Dashboard({ data }: Props) {
const [videoT, setVideoT] = useState(0)
const [addingFrame, setAddingFrame] = useState(false)
const [expanded, setExpanded] = useState<Set<string>>(new Set())
const [panelPos, setPanelPos] = useState<{ left: number; top: number } | null>(null)
const tileRefs = useRef<Record<string, HTMLButtonElement | null>>({})
const fileRef = useRef<HTMLInputElement>(null)
const videoRef = useRef<HTMLVideoElement>(null)
@@ -133,9 +135,21 @@ export function Dashboard({ data }: Props) {
{ key: "compose", title: "合成", type: "output", icon: <FileVideo className="h-3.5 w-3.5" />, step: 10 },
]
// 单选展开toggle 同一 key = 收起;点其他 key = 切换
const toggleTile = (key: string) => setExpanded((prev) => (prev.has(key) ? new Set() : new Set([key])))
const closeTile = (_key: string) => setExpanded(new Set())
// 单选展开toggle 同一 key = 收起;点其他 key = 切换;并记录 tile 位置让 panel 跟随
const toggleTile = (key: string) => {
if (expanded.has(key)) {
setExpanded(new Set())
setPanelPos(null)
return
}
setExpanded(new Set([key]))
const el = tileRefs.current[key]
if (el) {
const r = el.getBoundingClientRect()
setPanelPos({ left: r.left, top: r.bottom + 6 })
}
}
const closeTile = (_key: string) => { setExpanded(new Set()); setPanelPos(null) }
const Tile = ({ tkey, rowSpan }: { tkey: string; rowSpan?: boolean }) => {
const t = TILES.find((x) => x.key === tkey)!
@@ -143,6 +157,7 @@ export function Dashboard({ data }: Props) {
const isOpen = expanded.has(t.key)
return (
<button
ref={(el) => { tileRefs.current[t.key] = el }}
type="button"
onClick={() => toggleTile(t.key)}
title={colSummary[t.key]}
@@ -187,14 +202,14 @@ export function Dashboard({ data }: Props) {
<Tile tkey="compose" />
</div>
{/* 展开面板 — 单列宽度,居中,卡片竖向堆叠 */}
{expanded.size > 0 && (
<div className="flex justify-center px-4 pb-3" style={{ maxHeight: "52vh" }}>
{/* 展开面板 — 跟随被点 tile 的位置,从 tile 正下方冒出fixed 定位) */}
{expanded.size > 0 && panelPos && (
<div className="fixed z-40" style={{ left: Math.max(8, Math.min(panelPos.left, window.innerWidth - 376)), top: panelPos.top, maxHeight: "calc(100vh - " + panelPos.top + "px - 16px)" }}>
{TILES.filter((t) => expanded.has(t.key)).map((t) => (
<section
key={t.key}
className="rounded-xl border border-white/10 bg-black/30 backdrop-blur-xl overflow-hidden flex flex-col"
style={{ width: 360, maxHeight: "52vh" }}
className="rounded-xl border border-white/10 bg-black/40 backdrop-blur-xl overflow-hidden flex flex-col shadow-2xl"
style={{ width: 360, maxHeight: "calc(100vh - " + panelPos.top + "px - 16px)" }}
>
<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">
@@ -211,7 +226,7 @@ export function Dashboard({ data }: Props) {
<X className="h-3.5 w-3.5" />
</button>
</div>
<div className="overflow-y-auto p-3 bg-black/20">
<div className="overflow-y-auto p-3 bg-black/20 flex-1">
{renderSection(t.key)}
</div>
</section>