This commit is contained in:
Henry Hiles 2022-01-27 11:17:37 -05:00
parent d8146c3723
commit abdffe2e7a
7 changed files with 1184 additions and 51 deletions

1051
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -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"

View file

@ -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 })
}) })

View file

@ -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);

View file

@ -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
View 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>

View file

@ -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"