// app/meeting/[room]/page.tsx 'use client' import { useState, useEffect, useRef } from 'react' import { LiveKitRoom, VideoConference } from '@livekit/components-react' import { Button } from '@/components/ui/button' import { Input } from '@/components/ui/input' import { Card } from '@/components/ui/card' import { ScrollArea } from '@/components/ui/scroll-area' import '@livekit/components-styles'; import { Avatar, AvatarFallback } from '@/components/ui/avatar' import { Send, Bot } from 'lucide-react' export default function MeetRoomPage() { const [name, setName] = useState(''); const [roomName, setRoomName] = useState('General Bots'); const [token, setToken] = useState('') const [isConnected, setIsConnected] = useState(false) const [messages, setMessages] = useState>([]) const [inputMessage, setInputMessage] = useState('') const [micEnabled] = useState(true) const [cameraEnabled] = useState(true) const [botTyping, setBotTyping] = useState(false) const botConnectionRef = useRef(null) // Connect to LiveKit room const connectToRoom = async () => { try { const resp = await fetch(`https://generalbots.online/PROD-GeneralBots006/meeting-token?room=${roomName}&identity=${name || 'user'}`) const data = await resp.json() setToken(data.token) setIsConnected(true) // Connect bot when first user joins await connectBot() } catch (e) { console.error(e) } } // Connect to Bot Framework via Next.js API proxy const connectBot = async () => { try { const response = await fetch('https://generalbots.online/directline/PROD-GeneralBots006/conversations', { method: 'POST', headers: { 'Content-Type': 'application/json', }, }) const data = await response.json() // Then connect using WebSocket (which doesn't have CORS restrictions) const { DirectLine } = await import('botframework-directlinejs') const userId = `user_${Math.random().toString(36).slice(2)}` botConnectionRef.current = new DirectLine({ domain: 'https://generalbots.online/directline/PROD-GeneralBots006', userId: userId, userIdOnStartConversation: userId, conversationId: data.conversationId, webSocket: false // Force WebSocket connection } as any); botConnectionRef.current.setUserId(userId); // Listen for bot responses botConnectionRef.current.activity$.subscribe((activity: any) => { console.log('Bot activity:', activity) if (activity.text) { setBotTyping(false) setMessages(prev => [...prev, { sender: 'General Bots', text: activity.text, isBot: true }]) speak(activity.text) } }); // Send welcome message setMessages(prev => [...prev, { sender: 'System', text: 'General Bots joined the meeting', isBot: true }]); } catch (error) { console.error('Error connecting to bot:', error); setMessages(prev => [...prev, { sender: 'System', text: 'Failed to connect General Bots', isBot: true }]); } } // Text-to-Speech for bot responses const speak = (text: string) => { if ('speechSynthesis' in window) { const utterance = new SpeechSynthesisUtterance(text) utterance.rate = 1.0 utterance.pitch = 1.0 speechSynthesis.speak(utterance) } } // Send message to bot const sendToBot = (text: string, sender: string) => { if (!text.trim() || !botConnectionRef.current) return setMessages(prev => [...prev, { sender, text, isBot: false }]) setBotTyping(true) botConnectionRef.current.postActivity({ from: { id: botConnectionRef.current.userIdOnStartConversation, name: sender }, type: 'message', text }).subscribe( () => { }, (err: any) => console.error('Error sending to bot:', err) ) } // Manual message send const sendMessage = () => { sendToBot(inputMessage, name) setInputMessage('') } useEffect(() => { if (isConnected) { // Setup code if needed } }, [isConnected]) if (!isConnected) { return (

Join Meeting

setName(e.target.value)} className="border-gray-300 focus:border-primary focus:ring-1 focus:ring-primary" /> setRoomName(e.target.value)} className="border-gray-300 focus:border-primary focus:ring-1 focus:ring-primary" />
) } return (
{/* Chat/Transcript Area - Improved readability and interaction */}
{messages.map((msg, i) => (
{msg.isBot ? ( ) : ( {msg.sender[0].toUpperCase()} )} {msg.sender}

{msg.text}

))} {botTyping && (
General Bots
)}
{/* Message Input - Enhanced with better visual feedback */}
setInputMessage(e.target.value)} placeholder="Type a message..." onKeyDown={(e) => e.key === 'Enter' && sendMessage()} className="flex-1 border-gray-300 focus:border-primary focus:ring-1 focus:ring-primary rounded-full px-4" />
) }