Working
This commit is contained in:
parent
d8146c3723
commit
abdffe2e7a
7 changed files with 1184 additions and 51 deletions
1051
package-lock.json
generated
1051
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -9,7 +9,10 @@
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"socket.io": "^4.4.1"
|
"ejs": "^3.1.6",
|
||||||
|
"express": "^4.17.2",
|
||||||
|
"socket.io": "^4.4.1",
|
||||||
|
"uuid": "^8.3.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"nodemon": "^2.0.15"
|
"nodemon": "^2.0.15"
|
||||||
|
|
|
@ -2,7 +2,8 @@ import moment from "https://jspm.dev/moment"
|
||||||
import { io } from "https://cdn.socket.io/4.3.2/socket.io.esm.min.js"
|
import { io } from "https://cdn.socket.io/4.3.2/socket.io.esm.min.js"
|
||||||
const socket = io(":3000")
|
const socket = io(":3000")
|
||||||
const messageButton = document.querySelector("#send")
|
const messageButton = document.querySelector("#send")
|
||||||
const nameButton = document.querySelector("button")
|
const nameButton = document.querySelector("#name")
|
||||||
|
const roomContainer = document.querySelector("#room-container")
|
||||||
const nameInput = document.querySelector("input")
|
const nameInput = document.querySelector("input")
|
||||||
const messageInput = document.querySelector("textarea")
|
const messageInput = document.querySelector("textarea")
|
||||||
|
|
||||||
|
@ -34,29 +35,42 @@ const addMessage = (messageObject) => {
|
||||||
document.querySelector("#messages").prepend(messageDiv)
|
document.querySelector("#messages").prepend(messageDiv)
|
||||||
}
|
}
|
||||||
|
|
||||||
nameButton.addEventListener("click", () => {
|
socket.on("room-created", (room) => {
|
||||||
if (!nameInput.value) return (nameInput.required = true)
|
const roomItem = document.createElement("li")
|
||||||
document.querySelector("#login").classList.add("done")
|
const roomLink = document.createElement("a")
|
||||||
socket.emit("new-user", nameInput.value)
|
roomLink.href = `/${room}`
|
||||||
addMessage({
|
roomLink.innerText = room
|
||||||
message: "You joined",
|
roomItem.append(roomLink)
|
||||||
isYours: true,
|
roomContainer.append(roomItem)
|
||||||
isSystem: true,
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
messageButton.addEventListener("click", () => {
|
if (nameButton)
|
||||||
if (!messageInput.value) return (messageInput.required = true)
|
nameButton.addEventListener("click", () => {
|
||||||
socket.emit("send-chat-message", messageInput.value)
|
if (!nameInput.value) return (nameInput.required = true)
|
||||||
addMessage({ user: "you", message: messageInput.value, isYours: true })
|
document.querySelector("#login").classList.add("done")
|
||||||
messageInput.value = ""
|
socket.emit("new-user", roomName, nameInput.value)
|
||||||
})
|
addMessage({
|
||||||
|
message: "You joined",
|
||||||
|
isYours: true,
|
||||||
|
isSystem: true,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
if (messageButton)
|
||||||
|
messageButton.addEventListener("click", () => {
|
||||||
|
if (!messageInput.value) return (messageInput.required = true)
|
||||||
|
messageInput.required = false
|
||||||
|
socket.emit("send-chat-message", roomName, messageInput.value)
|
||||||
|
addMessage({ user: "you", message: messageInput.value, isYours: true })
|
||||||
|
messageInput.value = ""
|
||||||
|
})
|
||||||
|
|
||||||
socket.on("chat-message", (message, user) => {
|
socket.on("chat-message", (message, user) => {
|
||||||
addMessage({ message, user })
|
addMessage({ message, user })
|
||||||
})
|
})
|
||||||
|
|
||||||
socket.on("user-connected", (name) => {
|
socket.on("user-connected", (name) => {
|
||||||
|
socket.emit("join-room", ROOM_ID)
|
||||||
addMessage({ message: `${name} joined`, isSystem: true })
|
addMessage({ message: `${name} joined`, isSystem: true })
|
||||||
})
|
})
|
||||||
|
|
|
@ -30,7 +30,7 @@ footer {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
nav a {
|
a {
|
||||||
margin: 0 0.5em;
|
margin: 0 0.5em;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
width: fit-content;
|
width: fit-content;
|
||||||
|
@ -38,8 +38,12 @@ nav a {
|
||||||
grid-template-columns: 1fr 500px;
|
grid-template-columns: 1fr 500px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
nav:first-child a {
|
nav:first-child a {
|
||||||
font-size: 1.5em;
|
font-size: 1.5em !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
footer {
|
footer {
|
||||||
|
@ -115,6 +119,13 @@ button:hover {
|
||||||
color: white;
|
color: white;
|
||||||
border-radius: 20px;
|
border-radius: 20px;
|
||||||
}
|
}
|
||||||
|
#main-content {
|
||||||
|
background-color: var(--primary);
|
||||||
|
color: white;
|
||||||
|
display: flex;
|
||||||
|
padding: 30px;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
#messages {
|
#messages {
|
||||||
background-color: var(--primary);
|
background-color: var(--primary);
|
68
server.js
68
server.js
|
@ -1,27 +1,71 @@
|
||||||
const io = require("socket.io")(3000, {
|
const express = require("express")
|
||||||
|
const app = express()
|
||||||
|
const server = require("http").Server(app)
|
||||||
|
const io = require("socket.io")(server, {
|
||||||
cors: {
|
cors: {
|
||||||
origin: [
|
origin: [
|
||||||
"http://localhost:5500",
|
"http://localhost:5500",
|
||||||
"http://127.0.0.1:5500",
|
"http://127.0.0.1:5500",
|
||||||
"http//192.168.1.226:5500",
|
"http//192.168.1.226:5500",
|
||||||
|
"http//192.168.1.226:5500",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const users = {}
|
app.set("views", "./views")
|
||||||
|
app.set("view engine", "ejs")
|
||||||
|
app.use(express.static("public"))
|
||||||
|
app.use(express.urlencoded({ extended: true }))
|
||||||
|
|
||||||
|
const getUserRooms = (socket) =>
|
||||||
|
Object.entries(rooms).reduce((names, [name, room]) => {
|
||||||
|
if (room.users[socket.id] != null) names.push(name)
|
||||||
|
return names
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const rooms = {}
|
||||||
|
|
||||||
|
app.get("/", (_, res) => {
|
||||||
|
res.render("index", { rooms: rooms })
|
||||||
|
})
|
||||||
|
|
||||||
|
app.post("/room", (req, res) => {
|
||||||
|
if (rooms[req.body.room] != null) {
|
||||||
|
return res.redirect("/")
|
||||||
|
}
|
||||||
|
rooms[req.body.room] = { users: {} }
|
||||||
|
res.redirect(req.body.room)
|
||||||
|
io.emit("room-created", req.body.room)
|
||||||
|
})
|
||||||
|
|
||||||
|
app.get("/:room", (req, res) => {
|
||||||
|
if (rooms[req.params.room] == null) {
|
||||||
|
return res.redirect("/")
|
||||||
|
}
|
||||||
|
res.render("room", { roomName: req.params.room })
|
||||||
|
})
|
||||||
|
|
||||||
|
server.listen(3000)
|
||||||
|
|
||||||
io.on("connection", (socket) => {
|
io.on("connection", (socket) => {
|
||||||
socket.on("new-user", (name) => {
|
socket.on("new-user", (room, name) => {
|
||||||
users[socket.id] = name
|
socket.join(room)
|
||||||
socket.broadcast.emit("user-connected", name)
|
rooms[room].users[socket.id] = name
|
||||||
|
socket.broadcast.to(room).emit("user-connected", name)
|
||||||
})
|
})
|
||||||
|
|
||||||
socket.on("send-chat-message", (message) =>
|
socket.on("send-chat-message", (room, message) => {
|
||||||
socket.broadcast.emit("chat-message", message, users[socket.id])
|
socket.broadcast
|
||||||
|
.to(room)
|
||||||
|
.emit("chat-message", message, rooms[room].users[socket.id])
|
||||||
|
})
|
||||||
|
|
||||||
|
socket.on("disconnect", () =>
|
||||||
|
getUserRooms(socket).forEach((room) => {
|
||||||
|
socket.broadcast
|
||||||
|
.to(room)
|
||||||
|
.emit("user-disconnected", rooms[room].users[socket.id])
|
||||||
|
delete rooms[room].users[socket.id]
|
||||||
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
socket.on("disconnect", () => {
|
|
||||||
socket.broadcast.emit("user-disconnected", users[socket.id])
|
|
||||||
delete users[socket.id]
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
43
views/index.ejs
Normal file
43
views/index.ejs
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Document</title>
|
||||||
|
<link rel="stylesheet" href="style.css" />
|
||||||
|
<script type="module" src="script.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<nav><a href="#">Home</a><a href="#">Also home</a></nav>
|
||||||
|
<!-- <% if("<%= roomName %>") {} else -->
|
||||||
|
<div id="main-content">
|
||||||
|
<div id="room-container">
|
||||||
|
<span>Joinable rooms:</span>
|
||||||
|
<ul>
|
||||||
|
<% Object.keys(rooms).forEach(room => { %>
|
||||||
|
<li><a href="/<%= room %>"><%= room %></a></li>
|
||||||
|
<% }) %>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<form action="/room" method="POST">
|
||||||
|
<label for="room"></label>
|
||||||
|
<input
|
||||||
|
id="room"
|
||||||
|
name="room"
|
||||||
|
type="text"
|
||||||
|
placeholder="Room Name"
|
||||||
|
/>
|
||||||
|
<button class="button-primary" type="submit">New Room</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<footer>
|
||||||
|
<a
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer"
|
||||||
|
href="https://github.com/Henry-Hiles"
|
||||||
|
>My Github</a
|
||||||
|
>
|
||||||
|
</footer>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -3,8 +3,11 @@
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Messaging</title>
|
<title>Messaging - Chatting</title>
|
||||||
<link rel="stylesheet" href="style.css" />
|
<link rel="stylesheet" href="style.css" />
|
||||||
|
<script>
|
||||||
|
const roomName = "<%= roomName %>"
|
||||||
|
</script>
|
||||||
<script type="module" src="script.js"></script>
|
<script type="module" src="script.js"></script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
@ -13,7 +16,7 @@
|
||||||
<h1 class="large-header">Login</h1>
|
<h1 class="large-header">Login</h1>
|
||||||
<div>
|
<div>
|
||||||
<input type="text" placeholder="Username" />
|
<input type="text" placeholder="Username" />
|
||||||
<button class="button-circle">
|
<button class="button-circle" id="name">
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
width="16"
|
width="16"
|
Reference in a new issue