Typing notification, user socketId saved to state

This commit is contained in:
notnull 2019-07-14 09:34:43 -04:00
parent 7051201e0d
commit e4aae7e158
4 changed files with 95 additions and 32 deletions

View File

@ -1,6 +1,7 @@
module.exports = io => {
io.on('connection', socket => {
console.log(`A socket connection to the server has been made: ${socket.id}`)
socket.broadcast.emit('user connection', socket.id)
socket.on('disconnect', () => {
console.log(`${socket.id} has disconnected.`)
@ -9,5 +10,9 @@ module.exports = io => {
socket.on('message', message => {
socket.broadcast.emit('message', message)
})
socket.on('typing', () => {
socket.broadcast.emit('typing')
})
})
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -1,5 +1,7 @@
import React from 'react'
import { Form, Row, Col, Button } from 'react-bootstrap'
import { Form, Row, Col, Button, Card, ListGroup, Image } from 'react-bootstrap'
//import ScrollToBottom from 'react-scroll-to-bottom'
import userImage from '../assets/default-user-image.png'
import uuid from 'uuid'
@ -8,20 +10,53 @@ import socket from '../socket'
class Chat extends React.Component {
constructor() {
super()
this.state = { text: '', messages: [] }
this.state = {
text: '',
messages: [],
user: {},
}
this.handleSubmit = this.handleSubmit.bind(this)
this.handleChange = this.handleChange.bind(this)
this.handleKey = this.handleKey.bind(this)
}
componentDidMount() {
this.scrollToBottom()
socket.on('typing', () => this.toggleTyping())
socket.on('message', message => {
this.addMessage(message)
})
socket.on('user connection', payload =>
console.log('a user has logged in:', payload)
)
socket.on('connect', () => {
console.log('Connected!')
this.setState({ user: { socketId: socket.id } })
})
}
componentDidUpdate() {
this.scrollToBottom()
}
scrollToBottom = () => {
this.messagesEnd.scrollIntoView({ behavior: 'smooth' })
}
handleChange(e) {
this.setState({ [e.target.name]: e.target.value })
}
toggleTyping() {
if (this.state.typing) return
this.setState({ typing: true })
setTimeout(() => this.setState({ typing: false }), 2000)
}
handleKey(e) {
socket.emit('typing')
}
addMessage(message) {
const messages = this.state.messages.concat(message)
this.setState({ messages })
@ -36,32 +71,59 @@ class Chat extends React.Component {
render() {
return (
<div className="mt-5">
<div style={{ height: '30rem' }}>
{this.state.messages.map(msg => (
<div>
{msg.userId}: {msg.text}
</div>
))}
</div>
<Form onSubmit={this.handleSubmit}>
<Form.Group as={Row}>
<Col xs={9} sm={10}>
<Form.Control
name="text"
autocomplete="off"
value={this.state.text}
onChange={this.handleChange}
/>
</Col>
<Col xs={1} sm={2}>
<Button type="submit" variant="dark" onSubmit={this.handleSubmit}>
Send
</Button>
</Col>
</Form.Group>
</Form>
</div>
<Card className="mt-5">
<Card.Body style={{ height: '60vh' }}>
<ListGroup style={{ height: '100%', overflowY: 'hidden' }}>
{this.state.messages.map(msg => (
<ListGroup.Item key={uuid()} className="my-2">
<Image
className={`mx-2 ${
socket.id === this.state.user.socketId ? 'float-right' : ''
}`}
style={{ height: '24px' }}
src={userImage}
/>
{msg.userId}: {msg.text}
</ListGroup.Item>
))}
<div
style={{ float: 'left', clear: 'both' }}
ref={el => {
this.messagesEnd = el
}}
/>
</ListGroup>
</Card.Body>
<Card.Body>
<Form onSubmit={this.handleSubmit}>
<Form.Group as={Row}>
<Col xs={9} sm={10}>
<Form.Control
name="text"
autoComplete="off"
value={this.state.text}
onChange={this.handleChange}
onKeyDown={this.handleKey}
/>
</Col>
<Col xs={1} sm={2}>
<Button
type="submit"
variant="dark"
onSubmit={this.handleSubmit}
>
Send
</Button>
</Col>
</Form.Group>
</Form>
{this.state.typing ? (
<div style={{ height: '2em' }}>Someone is typing...</div>
) : (
<div style={{ height: '2em' }} />
)}
</Card.Body>
</Card>
)
}
}

View File

@ -2,8 +2,4 @@ import io from 'socket.io-client'
const socket = io(window.location.origin)
socket.on('connect', () => {
console.log('Connected!')
})
export default socket