import { useMemo, useState } from 'react' import Avatar from './Avatar' import { IconLogout, IconPlus, IconSearch } from './icons' import { formatListTime, peerForConversation, userTitle } from '../lib/format' import type { Conversation, User } from '../lib/types' interface SidebarProps { className?: string conversations: Conversation[] loading: boolean error: string | null selectedId: number | null currentUser: User directory: Map peers: Record presence: Record typing: Record onSelect: (id: number) => void onNewChat: () => void onRetry: () => void onLogout: () => void } function previewOf(conversation: Conversation, currentUserId: number): string { const last = conversation.last_message if (!last) return 'Нет сообщений' const prefix = last.sender_id === currentUserId ? 'Вы: ' : '' return `${prefix}${last.body}` } export default function Sidebar({ className = '', conversations, loading, error, selectedId, currentUser, directory, peers, presence, typing, onSelect, onNewChat, onRetry, onLogout, }: SidebarProps) { const [query, setQuery] = useState('') const items = useMemo(() => { const term = query.trim().toLowerCase() return conversations .map((conversation) => { const peer = peerForConversation(conversation, peers, directory, currentUser.id) const title = peer ? userTitle(peer) : `Чат #${conversation.id}` return { conversation, peer, title, preview: previewOf(conversation, currentUser.id) } }) .filter((item) => !term || item.title.toLowerCase().includes(term) || item.preview.toLowerCase().includes(term)) }, [conversations, query, peers, directory, currentUser.id]) return ( ) }