import React, { createRef, useState, useEffect } from 'react'; import PropTypes from 'prop-types'; import * as config from '../../config'; // Styles import './Chat.css'; const Chat = (props) => { const [message, setMesssage] = useState(''); const [messages, setMessages] = useState([]); const [connection, setConnection] = useState(null); const [showPopup, setShowPopup] = useState(false); const chatRef = createRef(); const messagesEndRef = createRef(); useEffect(() => { const initChatConnection = async () => { const { Meeting, Attendee } = props.joinInfo; const messagingUrl = `${config.CHAT_WEBSOCKET}?MeetingId=${Meeting.MeetingId}&AttendeeId=${Attendee.AttendeeId}&JoinToken=${Attendee.JoinToken}`; const connectionInit = await new WebSocket(messagingUrl); if (config.DEBUG) console.log(connectionInit); connectionInit.onopen = (event) => { console.log('websocket is now open', event); }; connectionInit.addEventListener('message', (event) => { const data = event.data.split('::'); const username = data[0]; const newMessage = data.slice(1).join('::'); // in case the message contains the separator '::' setMessages((prevState) => { return [ ...prevState, { timestamp: Date.now(), username, message: newMessage, }, ]; }); }); setConnection(connectionInit); return () => { connectionInit.removeEventListener('message', () => { console.log('Message event cancelled'); }); }; }; initChatConnection(); }, []); useEffect(() => { const scrollToBottom = () => { messagesEndRef.current.scrollIntoView({ behavior: 'smooth' }); }; scrollToBottom(); }); const handleChange = (e) => { setMesssage(e.target.value); }; const handleKeyDown = (e) => { if (e.keyCode === 13) { // keyCode 13 is carriage return const { username } = props; if (message) { const data = `{ "message": "sendmessage", "data": "${username}::${message .replace(/\\/g, '\\\\') .replace(/"/g, '\\"')}" }`; connection.send(data); setMesssage(''); } } }; const handleRoomClick = (e) => { e.stopPropagation(); e.preventDefault(); const { title } = props; const link = `${window.location.origin}${window.location.pathname.replace( 'meeting', 'index.html', )}?action=join&room=${title}`; if (config.DEBUG) console.log(link); copyTextToClipboard(encodeURI(link)); }; const handleShowPopup = () => { // show popup message setShowPopup(true); // hide popup message after 2 seconds setTimeout(() => { setShowPopup(false); }, 2000); }; const copyTextToClipboard = (text) => { if (navigator.clipboard) { navigator.clipboard.writeText(text).then( () => { handleShowPopup(); if (config.DEBUG) console.log('Room link copied to clipboard'); }, (err) => { if (config.DEBUG) console.log('Could not copy text: ', err); }, ); } }; const parseUrls = (userInput) => { var urlRegExp = /(http(s)?:\/\/.)?(www\.)?[-a-zA-Z0-9@:%._~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_.~#?&//=]*)/g; let formattedMessage = userInput.replace(urlRegExp, (match) => { let formattedMatch = match; if (!match.startsWith('http')) { formattedMatch = `http://${match}`; } return `${match}`; }); return formattedMessage; }; const popup = showPopup ? 'show' : ''; return (
{messages.map((msg) => { let formattedMessage = parseUrls(msg.message); return (

{msg.username}

); })}
); }; Chat.propTypes = { chime: PropTypes.object, title: PropTypes.string, username: PropTypes.string, joinInfo: PropTypes.object, }; export default Chat;