|
| 1 | +import { useParams, useSearchParams, useNavigate } from 'react-router-dom'; |
| 2 | +import { useMockRoom } from '@/hooks/useMockRoom'; |
| 3 | +import { ControlBar } from '@/components/room/ControlBar'; |
| 4 | +import { UserList } from '@/components/room/UserList'; |
| 5 | +import { ChatArea } from '@/components/room/ChatArea'; |
| 6 | +import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; |
| 7 | +import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; |
| 8 | +import { Mic } from 'lucide-react'; |
| 9 | + |
| 10 | +const StreamRoom = () => { |
| 11 | + const { id } = useParams(); |
| 12 | + const [searchParams] = useSearchParams(); |
| 13 | + const navigate = useNavigate(); |
| 14 | + const role = searchParams.get('role') === 'host' ? 'host' : 'listener'; |
| 15 | + |
| 16 | + const { |
| 17 | + status, |
| 18 | + me, |
| 19 | + users, |
| 20 | + messages, |
| 21 | + toggleMic, |
| 22 | + sendMessage, |
| 23 | + goLive, |
| 24 | + endStream |
| 25 | + } = useMockRoom(id || 'default', 'stream', role); |
| 26 | + |
| 27 | + const host = users.find(u => u.role === 'host'); |
| 28 | + |
| 29 | + return ( |
| 30 | + <div className="flex flex-col h-[calc(100vh-65px)] overflow-hidden bg-background"> |
| 31 | + <div className="flex-1 flex overflow-hidden"> |
| 32 | + {/* Main Stage */} |
| 33 | + <div className="flex-1 flex items-center justify-center p-6 relative"> |
| 34 | + {/* Background Blob */} |
| 35 | + <div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[300px] h-[300px] bg-primary/20 blur-[100px] rounded-full pointer-events-none" /> |
| 36 | + |
| 37 | + {status === 'live' ? ( |
| 38 | + <div className="flex flex-col items-center gap-6 z-10 animate-in fade-in zoom-in duration-500"> |
| 39 | + <div className="relative"> |
| 40 | + <Avatar className="h-40 w-40 border-4 border-primary ring-4 ring-primary/20"> |
| 41 | + <AvatarImage src={host?.avatar} /> |
| 42 | + <AvatarFallback className="text-4xl">{host?.name[0] || "H"}</AvatarFallback> |
| 43 | + </Avatar> |
| 44 | + {host?.isSpeaking && !host?.isMuted && ( |
| 45 | + <span className="absolute inset-0 rounded-full border-4 border-green-500 animate-ping opacity-75" /> |
| 46 | + )} |
| 47 | + <div className="absolute bottom-2 right-2 bg-primary text-primary-foreground p-2 rounded-full shadow-lg"> |
| 48 | + <Mic className="h-6 w-6" /> |
| 49 | + </div> |
| 50 | + </div> |
| 51 | + <div className="text-center space-y-2"> |
| 52 | + <h2 className="text-3xl font-bold">{host?.name || "Broadcaster"} is live</h2> |
| 53 | + <p className="text-xl text-muted-foreground animate-pulse">Listening...</p> |
| 54 | + </div> |
| 55 | + </div> |
| 56 | + ) : ( |
| 57 | + <div className="text-center z-10 space-y-4"> |
| 58 | + <h2 className="text-2xl font-semibold text-muted-foreground">Stream has not started yet</h2> |
| 59 | + {role === 'host' && ( |
| 60 | + <p className="text-sm">You are the host. Click "Start Broadcast" below when ready.</p> |
| 61 | + )} |
| 62 | + </div> |
| 63 | + )} |
| 64 | + </div> |
| 65 | + |
| 66 | + {/* Sidebar */} |
| 67 | + <div className="w-full md:w-[350px] border-l bg-background flex flex-col"> |
| 68 | + <Tabs defaultValue="chat" className="flex-1 flex flex-col"> |
| 69 | + <div className="px-4 pt-2"> |
| 70 | + <TabsList className="w-full"> |
| 71 | + <TabsTrigger value="chat" className="flex-1">Chat</TabsTrigger> |
| 72 | + <TabsTrigger value="users" className="flex-1">Users ({users.length})</TabsTrigger> |
| 73 | + </TabsList> |
| 74 | + </div> |
| 75 | + <TabsContent value="chat" className="flex-1 h-0 data-[state=active]:flex flex-col mt-0 border-0"> |
| 76 | + <ChatArea messages={messages} onSendMessage={sendMessage} /> |
| 77 | + </TabsContent> |
| 78 | + <TabsContent value="users" className="flex-1 h-0 data-[state=active]:flex flex-col mt-0 border-0"> |
| 79 | + <UserList users={users} currentUser={me} /> |
| 80 | + </TabsContent> |
| 81 | + </Tabs> |
| 82 | + </div> |
| 83 | + </div> |
| 84 | + |
| 85 | + {/* Control Bar */} |
| 86 | + <ControlBar |
| 87 | + user={me} |
| 88 | + status={status} |
| 89 | + onToggleMic={toggleMic} |
| 90 | + onLeave={() => navigate('/')} |
| 91 | + onGoLive={goLive} |
| 92 | + onEndStream={endStream} |
| 93 | + /> |
| 94 | + </div> |
| 95 | + ); |
| 96 | +}; |
| 97 | + |
| 98 | +export default StreamRoom; |
0 commit comments