Typing notification, user socketId saved to state
This commit is contained in:
parent
7051201e0d
commit
e4aae7e158
@ -1,6 +1,7 @@
|
|||||||
module.exports = io => {
|
module.exports = io => {
|
||||||
io.on('connection', socket => {
|
io.on('connection', socket => {
|
||||||
console.log(`A socket connection to the server has been made: ${socket.id}`)
|
console.log(`A socket connection to the server has been made: ${socket.id}`)
|
||||||
|
socket.broadcast.emit('user connection', socket.id)
|
||||||
|
|
||||||
socket.on('disconnect', () => {
|
socket.on('disconnect', () => {
|
||||||
console.log(`${socket.id} has disconnected.`)
|
console.log(`${socket.id} has disconnected.`)
|
||||||
@ -9,5 +10,9 @@ module.exports = io => {
|
|||||||
socket.on('message', message => {
|
socket.on('message', message => {
|
||||||
socket.broadcast.emit('message', message)
|
socket.broadcast.emit('message', message)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
socket.on('typing', () => {
|
||||||
|
socket.broadcast.emit('typing')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
BIN
src/assets/default-user-image.png
Normal file
BIN
src/assets/default-user-image.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
@ -1,5 +1,7 @@
|
|||||||
import React from 'react'
|
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'
|
import uuid from 'uuid'
|
||||||
|
|
||||||
@ -8,20 +10,53 @@ import socket from '../socket'
|
|||||||
class Chat extends React.Component {
|
class Chat extends React.Component {
|
||||||
constructor() {
|
constructor() {
|
||||||
super()
|
super()
|
||||||
this.state = { text: '', messages: [] }
|
this.state = {
|
||||||
|
text: '',
|
||||||
|
messages: [],
|
||||||
|
user: {},
|
||||||
|
}
|
||||||
this.handleSubmit = this.handleSubmit.bind(this)
|
this.handleSubmit = this.handleSubmit.bind(this)
|
||||||
this.handleChange = this.handleChange.bind(this)
|
this.handleChange = this.handleChange.bind(this)
|
||||||
|
this.handleKey = this.handleKey.bind(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
this.scrollToBottom()
|
||||||
|
|
||||||
|
socket.on('typing', () => this.toggleTyping())
|
||||||
socket.on('message', message => {
|
socket.on('message', message => {
|
||||||
this.addMessage(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) {
|
handleChange(e) {
|
||||||
this.setState({ [e.target.name]: e.target.value })
|
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) {
|
addMessage(message) {
|
||||||
const messages = this.state.messages.concat(message)
|
const messages = this.state.messages.concat(message)
|
||||||
this.setState({ messages })
|
this.setState({ messages })
|
||||||
@ -36,32 +71,59 @@ class Chat extends React.Component {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div className="mt-5">
|
<Card className="mt-5">
|
||||||
<div style={{ height: '30rem' }}>
|
<Card.Body style={{ height: '60vh' }}>
|
||||||
{this.state.messages.map(msg => (
|
<ListGroup style={{ height: '100%', overflowY: 'hidden' }}>
|
||||||
<div>
|
{this.state.messages.map(msg => (
|
||||||
{msg.userId}: {msg.text}
|
<ListGroup.Item key={uuid()} className="my-2">
|
||||||
</div>
|
<Image
|
||||||
))}
|
className={`mx-2 ${
|
||||||
</div>
|
socket.id === this.state.user.socketId ? 'float-right' : ''
|
||||||
<Form onSubmit={this.handleSubmit}>
|
}`}
|
||||||
<Form.Group as={Row}>
|
style={{ height: '24px' }}
|
||||||
<Col xs={9} sm={10}>
|
src={userImage}
|
||||||
<Form.Control
|
/>
|
||||||
name="text"
|
{msg.userId}: {msg.text}
|
||||||
autocomplete="off"
|
</ListGroup.Item>
|
||||||
value={this.state.text}
|
))}
|
||||||
onChange={this.handleChange}
|
<div
|
||||||
/>
|
style={{ float: 'left', clear: 'both' }}
|
||||||
</Col>
|
ref={el => {
|
||||||
<Col xs={1} sm={2}>
|
this.messagesEnd = el
|
||||||
<Button type="submit" variant="dark" onSubmit={this.handleSubmit}>
|
}}
|
||||||
Send
|
/>
|
||||||
</Button>
|
</ListGroup>
|
||||||
</Col>
|
</Card.Body>
|
||||||
</Form.Group>
|
<Card.Body>
|
||||||
</Form>
|
<Form onSubmit={this.handleSubmit}>
|
||||||
</div>
|
<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>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,4 @@ import io from 'socket.io-client'
|
|||||||
|
|
||||||
const socket = io(window.location.origin)
|
const socket = io(window.location.origin)
|
||||||
|
|
||||||
socket.on('connect', () => {
|
|
||||||
console.log('Connected!')
|
|
||||||
})
|
|
||||||
|
|
||||||
export default socket
|
export default socket
|
||||||
|
Loading…
Reference in New Issue
Block a user