import { useContext, useEffect, useState } from 'react' import { v4 as uuid } from 'uuid' import Box from '@mui/material/Box' import Divider from '@mui/material/Divider' import { ShellContext } from 'contexts/ShellContext' import { usePeerRoom, usePeerRoomAction } from 'hooks/usePeerRoom' import { PeerActions } from 'models/network' import { UnsentMessage, ReceivedMessage } from 'models/chat' import { MessageForm } from 'components/MessageForm' import { ChatTranscript } from 'components/ChatTranscript' export interface RoomProps { appId?: string getUuid?: typeof uuid roomId: string userId: string } export function Room({ appId = `${encodeURI(window.location.origin)}_${process.env.REACT_APP_NAME}`, getUuid = uuid, roomId, userId, }: RoomProps) { const [numberOfPeers, setNumberOfPeers] = useState(1) // Includes this peer const shellContext = useContext(ShellContext) const [isMessageSending, setIsMessageSending] = useState(false) const [messageLog, setMessageLog] = useState< Array >([]) const peerRoom = usePeerRoom( { appId, trackerUrls: process.env.REACT_APP_TRACKER_URL ? [process.env.REACT_APP_TRACKER_URL] : undefined, rtcConfig: { iceServers: [ { urls: 'stun:openrelay.metered.ca:80', }, { urls: 'turn:openrelay.metered.ca:80', username: 'openrelayproject', credential: 'openrelayproject', }, { urls: 'turn:openrelay.metered.ca:443', username: 'openrelayproject', credential: 'openrelayproject', }, { urls: 'turn:openrelay.metered.ca:443?transport=tcp', username: 'openrelayproject', credential: 'openrelayproject', }, ], }, }, roomId ) useEffect(() => { shellContext.setDoShowPeers(true) peerRoom.onPeerJoin(() => { shellContext.showAlert(`Someone has joined the room`, { severity: 'success', }) const newNumberOfPeers = numberOfPeers + 1 setNumberOfPeers(newNumberOfPeers) shellContext.setNumberOfPeers(newNumberOfPeers) }) peerRoom.onPeerLeave(() => { shellContext.showAlert(`Someone has left the room`, { severity: 'warning', }) const newNumberOfPeers = numberOfPeers - 1 setNumberOfPeers(newNumberOfPeers) shellContext.setNumberOfPeers(newNumberOfPeers) }) return () => { shellContext.setDoShowPeers(false) } }, [numberOfPeers, peerRoom, shellContext]) const [sendMessage, receiveMessage] = usePeerRoomAction( peerRoom, PeerActions.MESSAGE ) const performMessageSend = async (message: string) => { if (isMessageSending) return const unsentMessage: UnsentMessage = { authorId: userId, text: message, timeSent: Date.now(), id: getUuid(), } setIsMessageSending(true) setMessageLog([...messageLog, unsentMessage]) await sendMessage(unsentMessage) setMessageLog([ ...messageLog, { ...unsentMessage, timeReceived: Date.now() }, ]) setIsMessageSending(false) } receiveMessage(message => { setMessageLog([...messageLog, { ...message, timeReceived: Date.now() }]) }) const handleMessageSubmit = async (message: string) => { await performMessageSend(message) } return ( ) }