Skip to content

Commit be6f2a5

Browse files
committed
Added text chat functionality
1 parent b1a5f5b commit be6f2a5

File tree

4 files changed

+191
-3
lines changed

4 files changed

+191
-3
lines changed

client/public/index.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,5 +41,10 @@
4141
To begin the development, run `npm start` or `yarn start`.
4242
To create a production bundle, use `npm run build` or `yarn build`.
4343
-->
44+
<script type="text/javascript">
45+
window.onbeforeunload = function() {
46+
return true
47+
}
48+
</script>
4449
</body>
4550
</html>

client/src/App.css

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,3 +288,100 @@ a {
288288
box-shadow: 0 2.5em 0 0;
289289
}
290290
}
291+
292+
/* Chat Box */
293+
.chat-box{
294+
position: absolute;
295+
bottom: 0px;
296+
background: white;
297+
width: 355px;
298+
border-radius: 5px 5px 0px 0px;
299+
z-index: 100;
300+
}
301+
.chat-box-player1{
302+
right: 20px;
303+
}
304+
.chat-box-player2{
305+
left: 20px;
306+
}
307+
.chat-head{
308+
width: inherit;
309+
height: 45px;
310+
background: #2c3e50;
311+
border-radius: 5px 5px 0px 0px;
312+
}
313+
.chat-head h2{
314+
color: white;
315+
padding-top: 5px;
316+
display: inline-block;
317+
}
318+
.chat-head img{
319+
cursor: pointer;
320+
float: right;
321+
width: 25px;
322+
margin: 10px;
323+
}
324+
.chat-body{
325+
display: none;
326+
height: 205px;
327+
width: inherit;
328+
overflow: hidden auto;
329+
margin-bottom: 45px;
330+
}
331+
.chat-text{
332+
position: fixed;
333+
bottom: 0px;
334+
height: 45px;
335+
width: inherit;
336+
}
337+
.chat-text input{
338+
width: inherit;
339+
height: inherit;
340+
box-sizing: border-box;
341+
border: 1px solid #bdc3c7;
342+
padding: 10px;
343+
resize: none;
344+
outline: none;
345+
}
346+
.chat-text input:active, .chat-text input:focus, .chat-text input:hover{
347+
border-color: royalblue;
348+
}
349+
.msg-send{
350+
background: #406a4b;
351+
}
352+
.msg-receive{
353+
background: #595080;
354+
}
355+
.msg-send, .msg-receive{
356+
width: 285px;
357+
height: 35px;
358+
padding: 5px 5px 5px 10px;
359+
margin: 5px auto;
360+
border-radius: 3px;
361+
line-height: 30px;
362+
position: relative;
363+
color: white;
364+
}
365+
.msg-receive:before{
366+
content: '';
367+
width: 0px;
368+
height: 0px;
369+
position: absolute;
370+
border: 15px solid;
371+
border-color: transparent #595080 transparent transparent;
372+
left: -29px;
373+
top: 7px;
374+
}
375+
.msg-send:after{
376+
content: '';
377+
width: 0px;
378+
height: 0px;
379+
position: absolute;
380+
border: 15px solid;
381+
border-color: transparent transparent transparent #406a4b;
382+
right: -29px;
383+
top: 7px;
384+
}
385+
.msg-receive:hover, .msg-send:hover{
386+
opacity: .9;
387+
}

client/src/components/Game.js

Lines changed: 83 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ import gameOverSound from '../assets/sounds/game-over-sound.mp3'
2121
//DRAW 4 WILD - 600
2222

2323
let socket
24-
// const ENDPOINT = 'http://localhost:5000'
25-
const ENDPOINT = 'https://uno-online-multiplayer.herokuapp.com/'
24+
const ENDPOINT = 'http://localhost:5000'
25+
// const ENDPOINT = 'https://uno-online-multiplayer.herokuapp.com/'
2626

2727
const Game = (props) => {
2828
const data = queryString.parse(props.location.search)
@@ -32,6 +32,8 @@ const Game = (props) => {
3232
const [roomFull, setRoomFull] = useState(false)
3333
const [users, setUsers] = useState([])
3434
const [currentUser, setCurrentUser] = useState('')
35+
const [message, setMessage] = useState('')
36+
const [messages, setMessages] = useState([])
3537

3638
useEffect(() => {
3739
const connectionOptions = {
@@ -156,6 +158,13 @@ const Game = (props) => {
156158
socket.on('currentUserData', ({ name }) => {
157159
setCurrentUser(name)
158160
})
161+
162+
socket.on('message', message => {
163+
setMessages(messages => [ ...messages, message ])
164+
165+
const chatBody = document.querySelector('.chat-body')
166+
chatBody.scrollTop = chatBody.scrollHeight
167+
})
159168
}, [])
160169

161170
//some util functions
@@ -167,6 +176,23 @@ const Game = (props) => {
167176
return arr.length === 1 ? player : ''
168177
}
169178

179+
const toggleChatBox = () => {
180+
const chatBody = document.querySelector('.chat-body')
181+
if(chatBody.style.display === 'none')
182+
chatBody.style.display = 'block'
183+
else
184+
chatBody.style.display = 'none'
185+
}
186+
187+
const sendMessage= (event) => {
188+
event.preventDefault()
189+
if(message) {
190+
socket.emit('sendMessage', { message: message }, () => {
191+
setMessage('')
192+
})
193+
}
194+
}
195+
170196
//driver functions
171197
const onCardPlayedHandler = (played_card) => {
172198
//extract player who played the card
@@ -1196,14 +1222,15 @@ const Game = (props) => {
11961222
</span>
11971223
</div>
11981224

1225+
{/* PLAYER LEFT MESSAGES */}
11991226
{users.length===1 && currentUser === 'Player 2' && <h1 className='topInfoText'>Player 1 has left the game.</h1> }
1200-
12011227
{users.length===1 && currentUser === 'Player 1' && <h1 className='topInfoText'>Waiting for Player 2 to join the game.</h1> }
12021228

12031229
{users.length===2 && <>
12041230

12051231
{gameOver ? <div>{winner !== '' && <><h1>GAME OVER</h1><h2>{winner} wins!</h2></>}</div> :
12061232
<div>
1233+
{/* PLAYER 1 VIEW */}
12071234
{currentUser === 'Player 1' && <>
12081235
<div className='player2Deck' style={{pointerEvents: 'none'}}>
12091236
<p className='playerDeckText'>Player 2</p>
@@ -1241,8 +1268,35 @@ const Game = (props) => {
12411268
src={require(`../assets/cards-front/${item}.png`).default}
12421269
/>
12431270
))}
1271+
</div>
1272+
{/* <Chat Box Div */}
1273+
<div className="chatBoxWrapper">
1274+
<div className="chat-box chat-box-player1">
1275+
<div className="chat-head">
1276+
<h2>Chat Box</h2>
1277+
<img
1278+
onClick={toggleChatBox}
1279+
src="https://maxcdn.icons8.com/windows10/PNG/16/Arrows/angle_down-16.png"
1280+
title="Expand Arrow"
1281+
width="16" />
1282+
</div>
1283+
<div className="chat-body">
1284+
<div className="msg-insert">
1285+
{messages.map(msg => {
1286+
if(msg.user === 'Player 2')
1287+
return <div className="msg-receive">{msg.text}</div>
1288+
if(msg.user === 'Player 1')
1289+
return <div className="msg-send">{msg.text}</div>
1290+
})}
1291+
</div>
1292+
<div className="chat-text">
1293+
<input type='text' placeholder='Type a message...' value={message} onChange={event => setMessage(event.target.value)} onKeyPress={event => event.key==='Enter' && sendMessage(event)} />
1294+
</div>
1295+
</div>
1296+
</div>
12441297
</div> </> }
12451298

1299+
{/* PLAYER 2 VIEW */}
12461300
{currentUser === 'Player 2' && <>
12471301
<div className='player1Deck' style={{pointerEvents: 'none'}}>
12481302
<p className='playerDeckText'>Player 1</p>
@@ -1280,6 +1334,32 @@ const Game = (props) => {
12801334
src={require(`../assets/cards-front/${item}.png`).default}
12811335
/>
12821336
))}
1337+
</div>
1338+
{/* <Chat Box Div */}
1339+
<div className="chatBoxWrapper">
1340+
<div className="chat-box chat-box-player2">
1341+
<div className="chat-head">
1342+
<h2>Chat Box</h2>
1343+
<img
1344+
onClick={toggleChatBox}
1345+
src="https://maxcdn.icons8.com/windows10/PNG/16/Arrows/angle_down-16.png"
1346+
title="Expand Arrow"
1347+
width="16" />
1348+
</div>
1349+
<div className="chat-body">
1350+
<div className="msg-insert">
1351+
{messages.map(msg => {
1352+
if(msg.user === 'Player 1')
1353+
return <div className="msg-receive">{msg.text}</div>
1354+
if(msg.user === 'Player 2')
1355+
return <div className="msg-send">{msg.text}</div>
1356+
})}
1357+
</div>
1358+
<div className="chat-text">
1359+
<input type='text' placeholder='Type a message...' value={message} onChange={event => setMessage(event.target.value)} onKeyPress={event => event.key==='Enter' && sendMessage(event)} />
1360+
</div>
1361+
</div>
1362+
</div>
12831363
</div> </> }
12841364
</div> }
12851365
</> }

server.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ io.on('connection', socket => {
4545
io.to(user.room).emit('updateGameState', gameState)
4646
})
4747

48+
socket.on('sendMessage', (payload, callback) => {
49+
const user = getUser(socket.id)
50+
io.to(user.room).emit('message', {user: user.name, text: payload.message})
51+
callback()
52+
})
53+
4854
socket.on('disconnect', () => {
4955
const user = removeUser(socket.id)
5056
if(user)

0 commit comments

Comments
 (0)