import { useCallback, useEffect, useRef, useState } from 'react'; import { AvatarPicker } from './AvatarPicker'; import type { SessionSummary } from '../types'; import { getSessionListLabel, groupSessionsByDate } from '../utils/sessions'; function formatSessionTime(iso?: string): string { if (!iso) return ''; const date = new Date(iso); if (Number.isNaN(date.getTime())) return ''; const now = new Date(); const isToday = date.getFullYear() === now.getFullYear() && date.getMonth() === now.getMonth() && date.getDate() === now.getDate(); if (isToday) { return date.toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' }); } return date.toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' }); } function CloseIcon() { return ( ); } type HistorySidebarProps = { open: boolean; sessions: SessionSummary[]; activeSessionId?: string; loading: boolean; loadingMore: boolean; hasMore: boolean; searchQuery: string; onClose: () => void; onSelect: (sessionId: string) => void; onNew: () => void; onDelete: (sessionId: string) => void; onLoadMore: () => void; onSearchChange: (query: string) => void; }; export function HistorySidebar({ open, sessions, activeSessionId, loading, loadingMore, hasMore, searchQuery, onClose, onSelect, onNew, onDelete, onLoadMore, onSearchChange, }: HistorySidebarProps) { const bodyRef = useRef(null); const [pendingDeleteId, setPendingDeleteId] = useState(null); const [pendingSelectId, setPendingSelectId] = useState(null); useEffect(() => { if (open) { setPendingDeleteId(null); setPendingSelectId(null); } }, [open, sessions.length]); const handleScroll = useCallback(() => { const el = bodyRef.current; if (!el) return; const nearBottom = el.scrollHeight - el.scrollTop - el.clientHeight < 80; if (nearBottom && hasMore && !loadingMore && !loading) { onLoadMore(); } }, [hasMore, loading, loadingMore, onLoadMore]); const handleDeleteClick = useCallback((sessionId: string) => { setPendingSelectId(null); setPendingDeleteId(sessionId); }, []); const handleConfirmDelete = useCallback( (sessionId: string) => { setPendingDeleteId(null); onDelete(sessionId); }, [onDelete], ); const handleCancelDelete = useCallback(() => { setPendingDeleteId(null); }, []); const handleSelectClick = useCallback( (sessionId: string) => { if (pendingDeleteId === sessionId) return; if (activeSessionId === sessionId) { setPendingSelectId(null); onSelect(sessionId); return; } if (pendingSelectId === sessionId) { setPendingSelectId(null); onSelect(sessionId); return; } setPendingSelectId(sessionId); }, [activeSessionId, onSelect, pendingDeleteId, pendingSelectId], ); if (!open) return null; const sessionGroups = groupSessionsByDate(sessions); return ( <> > ); }