fix: show selected session detail beside sidebar
This commit is contained in:
@@ -291,7 +291,7 @@ export default function Home() {
|
||||
onPick={id => setCurrent(sessions.find(s => s.id === id) ?? null)}
|
||||
onNew={() => setCurrent(null)}
|
||||
/>
|
||||
<main className="flex-1 overflow-y-auto">
|
||||
<main className={`flex-1 overflow-y-auto transition-[padding] duration-200 ${current && sidebarOpen ? 'pl-[340px]' : ''}`}>
|
||||
<div className="mx-auto max-w-[1240px] px-10 py-8">
|
||||
<header className="flex items-center justify-between mb-8 gap-4">
|
||||
<div className="flex items-center gap-3 min-w-0">
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
'use client';
|
||||
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import type { GenSession } from '@/lib/types';
|
||||
|
||||
function modeLabel(mode?: GenSession['inputMode']) {
|
||||
@@ -87,6 +88,28 @@ export default function Sidebar({
|
||||
onPick: (id: string) => void;
|
||||
onNew: () => void;
|
||||
}) {
|
||||
const rootRef = useRef<HTMLElement | null>(null);
|
||||
const rowRefs = useRef<Record<string, HTMLDivElement | null>>({});
|
||||
const [detailTop, setDetailTop] = useState(140);
|
||||
|
||||
const activeSession = sessions.find(session => session.id === currentId) ?? null;
|
||||
|
||||
function syncDetailTop() {
|
||||
if (!currentId) return;
|
||||
const row = rowRefs.current[currentId];
|
||||
const root = rootRef.current;
|
||||
if (!row || !root) return;
|
||||
const rowRect = row.getBoundingClientRect();
|
||||
const rootRect = root.getBoundingClientRect();
|
||||
const rawTop = rowRect.top - rootRect.top;
|
||||
const maxTop = Math.max(96, rootRect.height - 360);
|
||||
setDetailTop(Math.min(Math.max(96, rawTop), maxTop));
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
syncDetailTop();
|
||||
}, [currentId, sessions.length, open]);
|
||||
|
||||
if (!open) {
|
||||
return (
|
||||
<aside className="glass-sidebar w-12 shrink-0 flex flex-col items-center py-4">
|
||||
@@ -104,7 +127,7 @@ export default function Sidebar({
|
||||
}
|
||||
|
||||
return (
|
||||
<aside className="flex shrink-0 items-stretch">
|
||||
<aside ref={rootRef} className="relative flex shrink-0 items-stretch overflow-visible">
|
||||
<div className="glass-sidebar w-72 shrink-0 flex flex-col">
|
||||
<div className="px-4 pt-5 pb-3 flex items-center gap-3">
|
||||
<div className="w-8 h-8 rounded-[8px] bg-gradient-to-br from-[#e6f578] to-[#d6b36a] flex items-center justify-center shadow-glow-violet">
|
||||
@@ -143,7 +166,7 @@ export default function Sidebar({
|
||||
最近会话
|
||||
</div>
|
||||
|
||||
<div className="flex-1 overflow-y-auto px-3 pb-4 space-y-1">
|
||||
<div className="flex-1 overflow-y-auto px-3 pb-4 space-y-1" onScroll={syncDetailTop}>
|
||||
{sessions.length === 0 && (
|
||||
<div className="px-3 py-12 text-center text-xs text-white/30">
|
||||
还没有生成记录
|
||||
@@ -153,7 +176,11 @@ export default function Sidebar({
|
||||
const selectedCount = s.images.filter(i => i.status === 'selected').length;
|
||||
const active = currentId === s.id;
|
||||
return (
|
||||
<div key={s.id} className="relative">
|
||||
<div
|
||||
key={s.id}
|
||||
ref={node => { rowRefs.current[s.id] = node; }}
|
||||
className="relative"
|
||||
>
|
||||
<button
|
||||
onClick={() => onPick(s.id)}
|
||||
className={`w-full text-left px-3 py-2.5 rounded-[8px] text-xs transition-all ${
|
||||
@@ -179,7 +206,6 @@ export default function Sidebar({
|
||||
</span>
|
||||
</div>
|
||||
</button>
|
||||
{active && <ActiveSessionDetail session={s} />}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
@@ -189,6 +215,15 @@ export default function Sidebar({
|
||||
本地端口 4560 · 数据 / data
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{activeSession && (
|
||||
<div
|
||||
className="absolute left-full z-30 w-80 pl-3"
|
||||
style={{ top: detailTop }}
|
||||
>
|
||||
<ActiveSessionDetail session={activeSession} />
|
||||
</div>
|
||||
)}
|
||||
</aside>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user