1
0
mirror of https://github.com/mizanxali/uno-online synced 2024-11-23 11:14:56 +00:00

Added text chat functionality

This commit is contained in:
Mizanali Panjwani 2021-03-03 03:59:42 +05:30
parent b1a5f5ba71
commit be6f2a5c3a
4 changed files with 191 additions and 3 deletions

View File

@ -41,5 +41,10 @@
To begin the development, run `npm start` or `yarn start`. To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`. To create a production bundle, use `npm run build` or `yarn build`.
--> -->
<script type="text/javascript">
window.onbeforeunload = function() {
return true
}
</script>
</body> </body>
</html> </html>

View File

@ -288,3 +288,100 @@ a {
box-shadow: 0 2.5em 0 0; box-shadow: 0 2.5em 0 0;
} }
} }
/* Chat Box */
.chat-box{
position: absolute;
bottom: 0px;
background: white;
width: 355px;
border-radius: 5px 5px 0px 0px;
z-index: 100;
}
.chat-box-player1{
right: 20px;
}
.chat-box-player2{
left: 20px;
}
.chat-head{
width: inherit;
height: 45px;
background: #2c3e50;
border-radius: 5px 5px 0px 0px;
}
.chat-head h2{
color: white;
padding-top: 5px;
display: inline-block;
}
.chat-head img{
cursor: pointer;
float: right;
width: 25px;
margin: 10px;
}
.chat-body{
display: none;
height: 205px;
width: inherit;
overflow: hidden auto;
margin-bottom: 45px;
}
.chat-text{
position: fixed;
bottom: 0px;
height: 45px;
width: inherit;
}
.chat-text input{
width: inherit;
height: inherit;
box-sizing: border-box;
border: 1px solid #bdc3c7;
padding: 10px;
resize: none;
outline: none;
}
.chat-text input:active, .chat-text input:focus, .chat-text input:hover{
border-color: royalblue;
}
.msg-send{
background: #406a4b;
}
.msg-receive{
background: #595080;
}
.msg-send, .msg-receive{
width: 285px;
height: 35px;
padding: 5px 5px 5px 10px;
margin: 5px auto;
border-radius: 3px;
line-height: 30px;
position: relative;
color: white;
}
.msg-receive:before{
content: '';
width: 0px;
height: 0px;
position: absolute;
border: 15px solid;
border-color: transparent #595080 transparent transparent;
left: -29px;
top: 7px;
}
.msg-send:after{
content: '';
width: 0px;
height: 0px;
position: absolute;
border: 15px solid;
border-color: transparent transparent transparent #406a4b;
right: -29px;
top: 7px;
}
.msg-receive:hover, .msg-send:hover{
opacity: .9;
}

View File

@ -21,8 +21,8 @@ import gameOverSound from '../assets/sounds/game-over-sound.mp3'
//DRAW 4 WILD - 600 //DRAW 4 WILD - 600
let socket let socket
// const ENDPOINT = 'http://localhost:5000' const ENDPOINT = 'http://localhost:5000'
const ENDPOINT = 'https://uno-online-multiplayer.herokuapp.com/' // const ENDPOINT = 'https://uno-online-multiplayer.herokuapp.com/'
const Game = (props) => { const Game = (props) => {
const data = queryString.parse(props.location.search) const data = queryString.parse(props.location.search)
@ -32,6 +32,8 @@ const Game = (props) => {
const [roomFull, setRoomFull] = useState(false) const [roomFull, setRoomFull] = useState(false)
const [users, setUsers] = useState([]) const [users, setUsers] = useState([])
const [currentUser, setCurrentUser] = useState('') const [currentUser, setCurrentUser] = useState('')
const [message, setMessage] = useState('')
const [messages, setMessages] = useState([])
useEffect(() => { useEffect(() => {
const connectionOptions = { const connectionOptions = {
@ -156,6 +158,13 @@ const Game = (props) => {
socket.on('currentUserData', ({ name }) => { socket.on('currentUserData', ({ name }) => {
setCurrentUser(name) setCurrentUser(name)
}) })
socket.on('message', message => {
setMessages(messages => [ ...messages, message ])
const chatBody = document.querySelector('.chat-body')
chatBody.scrollTop = chatBody.scrollHeight
})
}, []) }, [])
//some util functions //some util functions
@ -167,6 +176,23 @@ const Game = (props) => {
return arr.length === 1 ? player : '' return arr.length === 1 ? player : ''
} }
const toggleChatBox = () => {
const chatBody = document.querySelector('.chat-body')
if(chatBody.style.display === 'none')
chatBody.style.display = 'block'
else
chatBody.style.display = 'none'
}
const sendMessage= (event) => {
event.preventDefault()
if(message) {
socket.emit('sendMessage', { message: message }, () => {
setMessage('')
})
}
}
//driver functions //driver functions
const onCardPlayedHandler = (played_card) => { const onCardPlayedHandler = (played_card) => {
//extract player who played the card //extract player who played the card
@ -1196,14 +1222,15 @@ const Game = (props) => {
</span> </span>
</div> </div>
{/* PLAYER LEFT MESSAGES */}
{users.length===1 && currentUser === 'Player 2' && <h1 className='topInfoText'>Player 1 has left the game.</h1> } {users.length===1 && currentUser === 'Player 2' && <h1 className='topInfoText'>Player 1 has left the game.</h1> }
{users.length===1 && currentUser === 'Player 1' && <h1 className='topInfoText'>Waiting for Player 2 to join the game.</h1> } {users.length===1 && currentUser === 'Player 1' && <h1 className='topInfoText'>Waiting for Player 2 to join the game.</h1> }
{users.length===2 && <> {users.length===2 && <>
{gameOver ? <div>{winner !== '' && <><h1>GAME OVER</h1><h2>{winner} wins!</h2></>}</div> : {gameOver ? <div>{winner !== '' && <><h1>GAME OVER</h1><h2>{winner} wins!</h2></>}</div> :
<div> <div>
{/* PLAYER 1 VIEW */}
{currentUser === 'Player 1' && <> {currentUser === 'Player 1' && <>
<div className='player2Deck' style={{pointerEvents: 'none'}}> <div className='player2Deck' style={{pointerEvents: 'none'}}>
<p className='playerDeckText'>Player 2</p> <p className='playerDeckText'>Player 2</p>
@ -1241,8 +1268,35 @@ const Game = (props) => {
src={require(`../assets/cards-front/${item}.png`).default} src={require(`../assets/cards-front/${item}.png`).default}
/> />
))} ))}
</div>
{/* <Chat Box Div */}
<div className="chatBoxWrapper">
<div className="chat-box chat-box-player1">
<div className="chat-head">
<h2>Chat Box</h2>
<img
onClick={toggleChatBox}
src="https://maxcdn.icons8.com/windows10/PNG/16/Arrows/angle_down-16.png"
title="Expand Arrow"
width="16" />
</div>
<div className="chat-body">
<div className="msg-insert">
{messages.map(msg => {
if(msg.user === 'Player 2')
return <div className="msg-receive">{msg.text}</div>
if(msg.user === 'Player 1')
return <div className="msg-send">{msg.text}</div>
})}
</div>
<div className="chat-text">
<input type='text' placeholder='Type a message...' value={message} onChange={event => setMessage(event.target.value)} onKeyPress={event => event.key==='Enter' && sendMessage(event)} />
</div>
</div>
</div>
</div> </> } </div> </> }
{/* PLAYER 2 VIEW */}
{currentUser === 'Player 2' && <> {currentUser === 'Player 2' && <>
<div className='player1Deck' style={{pointerEvents: 'none'}}> <div className='player1Deck' style={{pointerEvents: 'none'}}>
<p className='playerDeckText'>Player 1</p> <p className='playerDeckText'>Player 1</p>
@ -1280,6 +1334,32 @@ const Game = (props) => {
src={require(`../assets/cards-front/${item}.png`).default} src={require(`../assets/cards-front/${item}.png`).default}
/> />
))} ))}
</div>
{/* <Chat Box Div */}
<div className="chatBoxWrapper">
<div className="chat-box chat-box-player2">
<div className="chat-head">
<h2>Chat Box</h2>
<img
onClick={toggleChatBox}
src="https://maxcdn.icons8.com/windows10/PNG/16/Arrows/angle_down-16.png"
title="Expand Arrow"
width="16" />
</div>
<div className="chat-body">
<div className="msg-insert">
{messages.map(msg => {
if(msg.user === 'Player 1')
return <div className="msg-receive">{msg.text}</div>
if(msg.user === 'Player 2')
return <div className="msg-send">{msg.text}</div>
})}
</div>
<div className="chat-text">
<input type='text' placeholder='Type a message...' value={message} onChange={event => setMessage(event.target.value)} onKeyPress={event => event.key==='Enter' && sendMessage(event)} />
</div>
</div>
</div>
</div> </> } </div> </> }
</div> } </div> }
</> } </> }

View File

@ -45,6 +45,12 @@ io.on('connection', socket => {
io.to(user.room).emit('updateGameState', gameState) io.to(user.room).emit('updateGameState', gameState)
}) })
socket.on('sendMessage', (payload, callback) => {
const user = getUser(socket.id)
io.to(user.room).emit('message', {user: user.name, text: payload.message})
callback()
})
socket.on('disconnect', () => { socket.on('disconnect', () => {
const user = removeUser(socket.id) const user = removeUser(socket.id)
if(user) if(user)