added chat functionality, namespaces

This commit is contained in:
notnull 2019-07-21 05:44:41 -04:00
parent 232d1a6aca
commit c47691b16a
4 changed files with 133 additions and 20 deletions

5
package-lock.json generated
View File

@ -8389,6 +8389,11 @@
} }
} }
}, },
"moment": {
"version": "2.24.0",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz",
"integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg=="
},
"morgan": { "morgan": {
"version": "1.9.1", "version": "1.9.1",
"resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.1.tgz", "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.1.tgz",

View File

@ -5,12 +5,14 @@
"dependencies": { "dependencies": {
"bootstrap": "^4.3.1", "bootstrap": "^4.3.1",
"cors": "^2.8.5", "cors": "^2.8.5",
"moment": "^2.24.0",
"morgan": "^1.9.1", "morgan": "^1.9.1",
"react": "^16.8.6", "react": "^16.8.6",
"react-dom": "^16.8.6", "react-dom": "^16.8.6",
"react-scripts": "3.0.1", "react-scripts": "3.0.1",
"socket.io": "^2.2.0", "socket.io": "^2.2.0",
"socket.io-client": "^2.2.0" "socket.io-client": "^2.2.0",
"uuid": "^3.3.2"
}, },
"scripts": { "scripts": {
"start": "react-scripts start", "start": "react-scripts start",

View File

@ -1,13 +1,39 @@
module.exports = io => { module.exports = io => {
io.on('connection', async socket => { io.on('connection', async 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.join('#chat')
io.emit(
'received rooms',
Object.keys(io.sockets.adapter.rooms)
.filter(r => r[0] === '#')
.map(k => ({
roomName: k,
sockets: Object.keys(io.sockets.adapter.rooms[k]['sockets']),
}))
)
socket.broadcast.emit('user connected', { socketId: socket.id })
socket.on('message', message => { socket.on('message', message => {
socket.broadcast.emit('message', message) io.to(message.room).emit(message)
})
socket.on('join', payload => {
console.log(payload.room)
socket.join({ room: payload.room })
})
socket.on('disconnect', async () => {
io.emit('user disconnected', { socketId: socket.id })
console.log(`${socket.id} has disconnected.`)
io.emit(
'received rooms',
Object.keys(io.sockets.adapter.rooms)
.filter(r => r[0] === '#')
.map(k => ({
roomName: k,
sockets: Object.keys(io.sockets.adapter.rooms[k]['sockets']),
}))
)
}) })
socket.on('disconnect', async () => console.log(io.sockets.adapter.rooms['#chat'])
console.log(`${socket.id} has disconnected.`)
)
}) })
} }

View File

@ -1,27 +1,67 @@
import React from 'react' import React from 'react'
import socket from './socket' import socket from './socket'
const initialState = { loading: true } import uuid from 'uuid'
const initialData = { message: 'Hello, world!' } import moment from 'moment'
const initialState = {
loading: true,
messages: [],
message: '',
rooms: [],
room: '/',
}
class App extends React.Component { class App extends React.Component {
constructor() { constructor() {
super() super()
this.state = initialState this.state = initialState
this.socket = socket this.socket = socket
this.handleChange = this.handleChange.bind(this)
this.handleSubmit = this.handleSubmit.bind(this)
this.joinRoom = this.joinRoom.bind(this)
} }
async fetchData() { async fetchData() {
try { this.setState({ loading: false })
const data = await initialData
this.setState({ ...data })
} catch (e) {
} finally {
this.setState({ loading: false })
}
} }
componentWillMount() {
componentDidMount() {
this.fetchData() this.fetchData()
this.socket.on('message', msg => {
const messages = this.state.messages.concat(msg)
this.setState({ messages })
})
this.socket.on('user connected', payload => {
console.log('a new user connected!', payload)
})
this.socket.on('user disconnected', payload => {
console.log('a user disconnected.', payload)
})
this.socket.on('received rooms', rooms => {
console.log(rooms)
this.setState({ rooms })
})
}
handleChange(e) {
this.setState({ [e.target.name]: e.target.value })
}
handleSubmit(e) {
e.preventDefault()
const message = {
id: uuid(),
date: moment().format('MMMM D YYYY, h:mm a'),
socketId: this.socket.id,
text: this.state.message,
room: this.state.room,
}
this.sendMessage(message)
this.setState({ message: '' })
} }
renderLoading() { renderLoading() {
return <div>loading...</div> return <div>loading...</div>
@ -30,7 +70,12 @@ class App extends React.Component {
renderError() { renderError() {
return <div>something went wrong.</div> return <div>something went wrong.</div>
} }
joinRoom(room) {
this.socket.emit('join', { room })
}
sendMessage(msg) {
this.socket.emit('message', msg)
}
renderApp() { renderApp() {
return ( return (
<main role="main" className="d-flex h-100 flex-column"> <main role="main" className="d-flex h-100 flex-column">
@ -39,10 +84,20 @@ class App extends React.Component {
<div className="d-flex h-100"> <div className="d-flex h-100">
{/*Side Bar 2*/} {/*Side Bar 2*/}
<div <div
className="d-none d-sm-block col-sm-2 bg-dark text-light p-2" className="d-flex flex-column col-sm-2 bg-dark text-light p-2"
id="sidebar2" id="sidebar2"
> >
<h5 className="border-bottom pb-2">Channels</h5> <h5 className=" border-bottom pb-2">Channels</h5>
{this.state.rooms.map(r => (
<button
key={r.roomName}
className="btn btn-dark d-flex"
onClick={() => this.joinRoom(r.roomName)}
>
<div className="mr-auto">{r.roomName}</div>
<div className="ml-auto">{r.sockets.length}</div>
</button>
))}
</div> </div>
{/*Main Section*/} {/*Main Section*/}
@ -53,8 +108,33 @@ class App extends React.Component {
</div> </div>
{/*Main Section Content*/} {/*Main Section Content*/}
<div className="d-flex flex-column border border-secondary flex-grow-1"> <div className="d-flex flex-column border border-secondary flex-grow-1">
<div className="bg-dark flex-grow-1 p-2">orange</div> <div className="bg-dark flex-grow-1 p-2 text-light">
<div className="bg-light p-2">blue</div> {this.state.messages
.filter(m => m.room === this.state.room)
.map(m => (
<div className="d-flex justify-content-between" key={m.id}>
<div>{m.date}</div>
<div>{m.socketId}</div>
<div>{m.text}</div>
</div>
))}
</div>
<form onSubmit={this.handleSubmit}>
<input
className="bg-light p-2 w-100"
name="message"
value={this.state.message}
placeholder="Enter message"
onChange={this.handleChange}
/>
<button
className="btn btn-dark"
type="submit"
onSubmit={this.handleSubmit}
>
submit
</button>
</form>
</div> </div>
</div> </div>
</div> </div>