fix: show selected session detail beside sidebar

This commit is contained in:
2026-05-19 20:26:30 +08:00
parent 39adcc54d3
commit 20bb8a0dac
2 changed files with 40 additions and 5 deletions

View File

@@ -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">

View File

@@ -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>
);
}