import { Copy, Download, Ellipsis, LogOut, MessageSquare, Search, Settings, Users, Wifi, WifiOff } from 'lucide-react' import { useEffect, useState } from 'react' import { Button } from '@/components/ui/button' import { LyricCalibration } from '@/components/Player/LyricCalibration' import { MusicDownloadDialog } from '@/components/Player/MusicDownloadDialog' import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, } from '@/components/ui/dropdown-menu' import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip' import { getMedianRTT } from '@/lib/clockSync' import { useRoomStore } from '@/stores/roomStore' import { usePlayerStore } from '@/stores/playerStore' import { useSocketContext } from '@/providers/socket-context' import { toast } from 'sonner' interface RoomHeaderProps { onOpenSearch: () => void onOpenChat: () => void onOpenSettings: () => void onOpenMembers: () => void onLeaveRoom: () => void chatUnreadCount: number } export function RoomHeader({ onOpenSearch, onOpenChat, onOpenSettings, onOpenMembers, onLeaveRoom, chatUnreadCount, }: RoomHeaderProps) { // Fine-grained selectors to avoid re-renders from queue/playState changes const roomName = useRoomStore((s) => s.room?.name) const roomId = useRoomStore((s) => s.room?.id) const userCount = useRoomStore((s) => s.room?.users.length ?? 0) const hasCurrentTrack = usePlayerStore((s) => Boolean(s.currentTrack)) const { isConnected } = useSocketContext() const [downloadOpen, setDownloadOpen] = useState(false) // Poll RTT from clockSync module every 3s const [rtt, setRtt] = useState(0) useEffect(() => { if (!isConnected) return const frame = requestAnimationFrame(() => setRtt(getMedianRTT())) const timer = setInterval(() => setRtt(getMedianRTT()), 3000) return () => { cancelAnimationFrame(frame) clearInterval(timer) } }, [isConnected]) const displayedRtt = isConnected ? rtt : 0 const rttColor = !isConnected ? 'text-destructive' : displayedRtt < 100 ? 'text-emerald-500/60' : displayedRtt < 300 ? 'text-yellow-500/60' : 'text-destructive/60' const copyRoomLink = () => { if (roomId) { navigator.clipboard.writeText(window.location.href) toast.success('房间链接已复制') } } return (
{roomId && ( <> {roomName} 复制房间链接 查看成员 )} {/* Connection status + RTT indicator */} {isConnected ? ( ) : ( )} {isConnected && ( {Math.round(displayedRtt)}ms )} {isConnected ? `已连接 · 延迟 ${Math.round(displayedRtt)}ms` : '连接断开,正在重连...'}
聊天 搜索点歌 下载音乐 {/* Desktop: inline settings & leave buttons */} 设置 离开房间 {/* Mobile: dropdown menu */} 设置 setDownloadOpen(true)}> 下载音乐 复制房间链接 离开房间
) }