some events

This commit is contained in:
Sergey Yarkov 2020-08-26 05:31:25 +03:00
parent 1b9a4ebb22
commit 41719a02ca
5 changed files with 96 additions and 29 deletions

View File

@ -4,7 +4,7 @@ import Header from './Header/Header'
import './ChatBox.scss' import './ChatBox.scss'
const ChatBox = ({ user }) => { const ChatBox = ({ user }) => {
const [online, setOnline] = React.useState(0)
const [messages, setMessages] = React.useState([]) const [messages, setMessages] = React.useState([])
const chatContentElement = React.useRef(null) const chatContentElement = React.useRef(null)
const inputMessageElement = React.useRef(null) const inputMessageElement = React.useRef(null)
@ -18,30 +18,45 @@ const ChatBox = ({ user }) => {
message.value = '' message.value = ''
} }
const ChatContent = () => <div ref={chatContentElement} className="chat-content"> const ChatContent = () => {
{messages.map((client, i) => { return (
<div ref={chatContentElement} className="chat-content">
return ( {messages.map((client, i) => {
<div key={i} className='message'> return (
<div className="message-username"> <div key={i}>
<p> {client.date !== null ? <div className='message'>
{client.username} <div className="message-username">
<span>{client.date}</span> <p>
</p> {client.username}
</div> <span>{client.date}</span>
<div className="message-text"> </p>
{client.message} </div>
</div> <div className="message-text">
{client.message}
</div>
</div> : <div className='info'>
<span>{client.message}</span>
</div>}
</div>
)
})}
</div> </div>
) )
})} }
</div>
const ChatOnline = () => {
return (
<div className='chat-online'>
<span>Online: {online}</span>
</div>
)
}
const ChatInput = () => { const ChatInput = () => {
return ( return (
<div className="chat-input"> <div className="chat-input">
<form onSubmit={sendMessage}> <form onSubmit={sendMessage}>
<input ref={inputMessageElement} required type="text" name='message' placeholder='message'/> <input ref={inputMessageElement} required type="text" name='message' placeholder='Type your message...'/>
<button> <button>
<svg width="25" height="23" viewBox="0 0 25 23" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg width="25" height="23" viewBox="0 0 25 23" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M23.5111 9.27032L3.34053 0.900689C2.49077 0.548052 1.53076 0.703179 0.835207 1.30533C0.139651 1.90757 -0.151267 2.8355 0.0760766 3.72696L1.87144 10.7676H10.6618C11.0663 10.7676 11.3942 11.0955 11.3942 11.5001C11.3942 11.9045 11.0663 12.2325 10.6618 12.2325H1.87144L0.0760766 19.2731C-0.151267 20.1646 0.139602 21.0925 0.835207 21.6947C1.53218 22.2981 2.49229 22.4513 3.34058 22.0994L23.5112 13.7298C24.4295 13.3487 25 12.4943 25 11.5001C25 10.5058 24.4295 9.65132 23.5111 9.27032Z" fill="#0070F3"/> <path d="M23.5111 9.27032L3.34053 0.900689C2.49077 0.548052 1.53076 0.703179 0.835207 1.30533C0.139651 1.90757 -0.151267 2.8355 0.0760766 3.72696L1.87144 10.7676H10.6618C11.0663 10.7676 11.3942 11.0955 11.3942 11.5001C11.3942 11.9045 11.0663 12.2325 10.6618 12.2325H1.87144L0.0760766 19.2731C-0.151267 20.1646 0.139602 21.0925 0.835207 21.6947C1.53218 22.2981 2.49229 22.4513 3.34058 22.0994L23.5112 13.7298C24.4295 13.3487 25 12.4943 25 11.5001C25 10.5058 24.4295 9.65132 23.5111 9.27032Z" fill="#0070F3"/>
@ -58,11 +73,17 @@ const ChatBox = ({ user }) => {
chatContentElement.current.scrollTop = chatContentElement.current.scrollHeight chatContentElement.current.scrollTop = chatContentElement.current.scrollHeight
inputMessageElement.current.focus() inputMessageElement.current.focus()
}) })
}, [setMessages]);
socket.on('user:connected', (username, online) => {
setOnline(online)
setMessages(messages => ([...messages, { message: `${username} Joined!`, username, date: null }]))
})
}, [setMessages, setOnline]);
return ( return (
<div className="chat"> <div className="chat">
<Header /> <Header />
<ChatOnline />
<ChatContent /> <ChatContent />
<ChatInput /> <ChatInput />
</div> </div>

View File

@ -1,12 +1,16 @@
.chat { .chat {
border-radius: 7px; border-radius: 7px;
box-shadow: 0px 0px 12px rgba(114, 114, 114, 0.21); border: 1px solid #F3F3F3;
margin-top: 4rem; margin-top: 4rem;
margin-bottom: 2rem; margin-bottom: 2rem;
position: relative; position: relative;
& .chat-content { & .chat-content {
height: 370px; height: 370px;
overflow-y: scroll; overflow-y: scroll;
& .info {
margin-bottom: 15px;
font-size: 15px;
}
& .message { & .message {
margin-bottom: 15px; margin-bottom: 15px;
& .message-username { & .message-username {
@ -32,8 +36,27 @@
} }
} }
} }
& .chat-online {
padding: 0 30px;
margin-top: 15px;
& span {
display: flex;
justify-content: flex-end;
align-items: center;
font-size: 15px;
}
& span::before {
content: '';
display: block;
margin-right: 10px;
border-radius: 50px;
background: #4ecd13;
width: 6px;
height: 6px;
}
}
& .chat-content, & .chat-input { & .chat-content, & .chat-input {
padding: 15px 30px; padding: 0 30px 15px 30px;
} }
& .chat-input { & .chat-input {
padding-bottom: 25px; padding-bottom: 25px;

View File

@ -1,4 +1,5 @@
import React from 'react'; import React from 'react';
import { socket } from '../../App'
import './EnterChat.scss' import './EnterChat.scss'
const EnterChat = ({ setUser }) => { const EnterChat = ({ setUser }) => {
@ -7,8 +8,8 @@ const EnterChat = ({ setUser }) => {
const loginHandler = e => { const loginHandler = e => {
e.preventDefault() e.preventDefault()
const username = e.target.elements.username.value.trim() const username = e.target.elements.username.value.trim()[0].toUpperCase() + e.target.elements.username.value.trim().slice(1)
const maxUserameLength = 20 const maxUsernameLength = 20
if (username === '') { if (username === '') {
setAuthError({ status: true, message: '*Invalid username!' }) setAuthError({ status: true, message: '*Invalid username!' })
@ -20,13 +21,14 @@ const EnterChat = ({ setUser }) => {
return return
} }
if (username.length >= maxUserameLength) { if (username.length >= maxUsernameLength) {
setAuthError({ status: true, message: `*Max username length: ${maxUserameLength}` }) setAuthError({ status: true, message: `*Max username length: ${maxUsernameLength}` })
return return
} }
setUser({ username: username[0].toUpperCase() + username.slice(1), isLoggedIn: true }) setUser({ username, isLoggedIn: true })
setAuthError({ status: false, message: '' }) setAuthError({ status: false, message: '' })
socket.emit('user:connected', username)
} }
return ( return (

View File

@ -4,7 +4,8 @@
"description": "", "description": "",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"start": "concurrently \"cd ./server && npm run start\" \"cd ./client && npm run start\"" "start": "concurrently \"cd ./server && npm run start\" \"cd ./client && npm run start\"",
"dev": "concurrently \"cd ./server && npm run dev\" \"cd ./client && npm run start\""
}, },
"repository": { "repository": {
"type": "git", "type": "git",

View File

@ -4,14 +4,34 @@ const io = require('socket.io')(http)
const PORT = process.env.PORT || 3001 const PORT = process.env.PORT || 3001
server.get('/', (req, res) => { server.get('/', (req, res) => {
res.send('Chat API') res.send('React Chat API')
}) })
io.on('connection', (socket) => { io.on('connection', (socket) => {
const users = []
let onlineCounter = 0
socket.on('user:connected', (username) => {
onlineCounter += 1
io.emit('user:connected', username, onlineCounter)
users.push(socket.id)
console.log(users)
})
socket.on('chat:message', (message, username, date) => { socket.on('chat:message', (message, username, date) => {
io.emit('chat:message', message, username, date) io.emit('chat:message', message, username, date)
}) })
socket.on('disconnecting', () => {
const userIndex = users.findIndex((id) => socket.id === id)
if (userIndex !== -1) {
users.splice(userIndex, 1)
}
})
}) })
http.listen(PORT, () => { http.listen(PORT, () => {