forked from Github/uno-online
Added text chat functionality
This commit is contained in:
parent
b1a5f5ba71
commit
be6f2a5c3a
@ -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>
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
@ -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> }
|
||||||
</> }
|
</> }
|
||||||
|
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user