import React, { useState, useMemo } from 'react'; import { useNavigate } from 'react-router-dom'; import { useServerStore } from '../../stores/serverStore'; import { useChatStore } from '../../stores/chatStore'; import { useUIStore } from '../../stores/uiStore'; import { Tooltip } from '../ui/Tooltip'; interface SidebarItemProps { id: string; name: string; icon?: string | null; active: boolean; onClick: () => void; type?: 'server' | 'dm' | 'action'; actionType?: 'add' | 'join' | 'explore'; hasUnread?: boolean; } function SidebarItem({ name, icon, active, onClick, type = 'server', actionType, hasUnread }: SidebarItemProps) { const [isHovered, setIsHovered] = useState(false); const firstLetter = name.charAt(0).toUpperCase(); const getPillHeight = () => { if (active) return 'h-10'; if (isHovered) return 'h-5'; if (hasUnread && !active) return 'h-2'; return 'h-2 scale-0'; }; const getButtonClasses = () => { const base = 'w-12 h-12 flex items-center justify-center transition-all duration-200 overflow-hidden relative group'; if (type === 'dm') { return `${base} ${active ? 'bg-discord-blurple rounded-[16px] text-white' : 'bg-discord-bg-primary rounded-[24px] hover:rounded-[16px] text-discord-text-primary hover:bg-discord-blurple hover:text-white'}`; } if (type === 'action') { return `${base} bg-discord-bg-primary rounded-[24px] hover:rounded-[16px] text-discord-green hover:bg-discord-green hover:text-white`; } return `${base} ${active ? 'bg-discord-blurple rounded-[16px] text-white' : 'bg-discord-bg-primary rounded-[24px] hover:rounded-[16px] text-discord-text-primary hover:bg-discord-blurple hover:text-white'}`; }; return (
setIsHovered(true)} onMouseLeave={() => setIsHovered(false)} > {/* Pill Indicator */} {(type === 'server' || type === 'dm') && (
)}
); } export function ServerSidebar() { const servers = useServerStore((s) => s.servers); const currentServerId = useServerStore((s) => s.currentServerId); const setCurrentServer = useServerStore((s) => s.setCurrentServer); const channelToServerMap = useServerStore((s) => s.channelToServerMap); const dmChannels = useServerStore((s) => s.dmChannels); const showDms = useUIStore((s) => s.showDms); const setShowDms = useUIStore((s) => s.setShowDms); const openModal = useUIStore((s) => s.openModal); const unreadChannels = useChatStore((s) => s.unreadChannels); const navigate = useNavigate(); // Compute which servers have unread channels const unreadServerIds = useMemo(() => { const ids = new Set(); for (const channelId of unreadChannels) { const serverId = channelToServerMap.get(channelId); if (serverId) ids.add(serverId); } return ids; }, [unreadChannels, channelToServerMap]); // Check if any DM channels are unread const hasDmUnread = useMemo(() => { for (const dm of dmChannels) { if (unreadChannels.has(dm.id)) return true; } return false; }, [unreadChannels, dmChannels]); const handleServerClick = (serverId: string) => { setCurrentServer(serverId); setShowDms(false); navigate(`/channels/${serverId}`); }; const handleDmClick = () => { setShowDms(true); setCurrentServer(null); navigate('/channels/@me'); }; return ( ); }