Skip to content

Instantly share code, notes, and snippets.

@3rdp
Created July 30, 2019 10:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 3rdp/80ea291779950a9f35c5d2b3033e5ae7 to your computer and use it in GitHub Desktop.
Save 3rdp/80ea291779950a9f35c5d2b3033e5ae7 to your computer and use it in GitHub Desktop.
{
"name": "hooks-chat",
"version": "0.1.0",
"private": true,
"dependencies": {
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-scripts": "3.0.1",
"use-immer": "^0.3.3",
"use-socket.io-client": "^1.0.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
import React, { useState, useEffect } from 'react';
import useSocket from 'use-socket.io-client';
import { useImmer } from 'use-immer';
import './App.css';
import Messages from './Messages';
import Online from './Online';
function App() {
const [id, setId] = useState('')
const [nameInput, setNameInput] = useState('');
const [room, setRoom] = useState('');
const [input, setInput] = useState('');
const [socket] = useSocket('https://open-chat-naostsaecf.now.sh');
socket.connect();
const [messages, setMessages] = useImmer([]);
const [online, setOnline] = useImmer([]);
// console.log(socket);
useEffect(()=>{
socket.on('message que', (nick, message) => {
setMessages(draft => {
draft.push([nick, message])
})
});
socket.on('update', message => {
setMessages(draft => {
draft.push(['', message]);
})
});
socket.on('people-list',people => {
let newState = [];
for(let person in people){
newState.push([people[person].id,people[person].nick]);
}
setOnline(draft=>{draft.push(...newState)});
});
socket.on('add-person',(nick,id)=>{
setOnline(draft => {
draft.push([id,nick])
})
});
socket.on('remove-person',id=>{
setOnline(draft => draft.filter(m => m[0] !== id))
});
socket.on('chat message',(nick,message)=>{
setMessages(draft => {draft.push([nick,message])})
});
}, 0);
const handleSubmit = e => {
e.preventDefault();
if (!nameInput) {
return alert("Name can't be empty");
}
setId(nameInput);
socket.emit("join", nameInput, room);
};
const handleSend = e => {
e.preventDefault();
if (input) {
socket.emit('chat message',input.trim(),room);
setInput('');
}
};
return id ? (
<section style={{ display: "flex", flexDirection: "row" }}>
<ul id="messages">
<Messages>{messages}</Messages>
</ul>
<ul id="online">
{" "}
&#x1f310; : <Online data={online} />{" "}
</ul>
<div id="sendform">
<form onSubmit={handleSend} style={{ display: "flex", position: "fixed" }}>
<input id="m" value={input} onChange={e => setInput(e.target.value)} />
<button style={{ width: "75px" }} type="submit">
Send
</button>
</form>
</div>
</section>
) : (
<div style={{ textAlign: "center", margin: "30vh auto", width: "70%" }}>
<form onSubmit={handleSubmit}>
<input
id="name"
onChange={e => setNameInput(e.target.value.trim())}
required
placeholder="What is your name .."
/>
<br />
<input
id="room"
onChange={e => setRoom(e.target.value.trim())}
placeholder="What is your room .."
/>
<br />
<button type="submit">Submit</button>
</form>
</div>
);
}
export default App;
import React from 'react'
import PropTypes from 'prop-types';
const Messages = props =>
props.children.map(
(m, index) => m[0] ? (
<li key={`${m[0]}-${index}-${m[1]}`}><strong>{m[0]}</strong> : <div className="innermsg">{m[1]}</div></li>
) : (
<li key={m[1]} className="update">{m[1]}</li>
)
);
Messages.propTypes = {
children: PropTypes.array.isRequired,
};
export default Messages;
import React from 'react'
const Online = props => props.data.map(user => {
const [id, username] = user;
return <li key={id} id={id}>{username}</li>;
});
export default Online;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment