mirror of
https://github.com/sergeyyarkov/react-chat-app.git
synced 2026-10-11 10:29:04 +03:00
some events
This commit is contained in:
parent
1b9a4ebb22
commit
41719a02ca
@ -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,11 +18,13 @@ const ChatBox = ({ user }) => {
|
|||||||
message.value = ''
|
message.value = ''
|
||||||
}
|
}
|
||||||
|
|
||||||
const ChatContent = () => <div ref={chatContentElement} className="chat-content">
|
const ChatContent = () => {
|
||||||
{messages.map((client, i) => {
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div key={i} className='message'>
|
<div ref={chatContentElement} className="chat-content">
|
||||||
|
{messages.map((client, i) => {
|
||||||
|
return (
|
||||||
|
<div key={i}>
|
||||||
|
{client.date !== null ? <div className='message'>
|
||||||
<div className="message-username">
|
<div className="message-username">
|
||||||
<p>
|
<p>
|
||||||
{client.username}
|
{client.username}
|
||||||
@ -32,16 +34,29 @@ const ChatBox = ({ user }) => {
|
|||||||
<div className="message-text">
|
<div className="message-text">
|
||||||
{client.message}
|
{client.message}
|
||||||
</div>
|
</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>
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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 (
|
||||||
|
|||||||
@ -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",
|
||||||
|
|||||||
@ -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, () => {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user