Some nice changes like a better grid that is more responsive.
This commit is contained in:
parent
099b038199
commit
0eab4c62ac
8 changed files with 78 additions and 73 deletions
|
@ -1,29 +1,34 @@
|
||||||
const socket = io("/")
|
|
||||||
const login = document.querySelector("#login")
|
|
||||||
const nameButton = document.querySelector("#name")
|
const nameButton = document.querySelector("#name")
|
||||||
const nameInput = document.querySelector("#name-input")
|
const nameInput = document.querySelector("#name-input")
|
||||||
const nameDisplay = document.querySelector("#name-display")
|
const nameDisplay = document.querySelector("#name-display")
|
||||||
|
|
||||||
|
const loginURL = new URL("login", window.location.origin)
|
||||||
|
try {
|
||||||
|
loginURL.searchParams.append("roomId", ROOM_ID)
|
||||||
|
} catch (error) {
|
||||||
|
if (!error instanceof ReferenceError) throw error
|
||||||
|
}
|
||||||
|
|
||||||
document
|
document
|
||||||
.querySelector("#change-name")
|
.querySelector("#change-name")
|
||||||
.addEventListener("click", () => login.classList.remove("done"))
|
?.addEventListener("click", () => (window.location = loginURL))
|
||||||
|
|
||||||
const yourName = localStorage.getItem("name")
|
const yourName = localStorage.getItem("name")
|
||||||
|
|
||||||
if (yourName) nameDisplay.innerText = yourName
|
if (!yourName && window.location.pathname != "/login")
|
||||||
else login.classList.remove("done")
|
window.location = loginURL
|
||||||
|
if (yourName && nameDisplay) nameDisplay.innerText = yourName
|
||||||
|
|
||||||
const validate = () => {
|
const validate = () => {
|
||||||
if (!nameInput.value) return (nameInput.required = true)
|
if (!nameInput.value) return (nameInput.required = true)
|
||||||
document.querySelector("#login").classList.add("done")
|
|
||||||
localStorage.setItem("name", nameInput.value)
|
localStorage.setItem("name", nameInput.value)
|
||||||
nameDisplay.innerText = nameInput.value
|
|
||||||
socket.emit("name-change", nameInput.value)
|
window.location.href =
|
||||||
|
new URLSearchParams(window.location.search).get("roomId") || "/"
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nameButton) nameButton.addEventListener("click", validate)
|
nameButton?.addEventListener?.("click", validate)
|
||||||
if (nameInput)
|
nameInput?.addEventListener?.(
|
||||||
nameInput.addEventListener(
|
|
||||||
"keydown",
|
"keydown",
|
||||||
(event) => event.keyCode == "13" && validate()
|
(event) => event.keyCode == "13" && validate()
|
||||||
)
|
)
|
||||||
|
|
|
@ -70,6 +70,8 @@ export const addVideoStream = (videoContainer, username, stream, isYours) => {
|
||||||
|
|
||||||
const video = videoContainer.querySelector("video")
|
const video = videoContainer.querySelector("video")
|
||||||
video.srcObject = stream
|
video.srcObject = stream
|
||||||
|
if (CSS.supports("::-webkit-media-controls-panel"))
|
||||||
|
video.controls = "controls"
|
||||||
video.addEventListener("loadedmetadata", () => video.play())
|
video.addEventListener("loadedmetadata", () => video.play())
|
||||||
if (isYours) {
|
if (isYours) {
|
||||||
video.muted = true
|
video.muted = true
|
||||||
|
|
|
@ -2,10 +2,14 @@ import { addVideoStream, connectToNewUser, showNoVideoPrompt } from "./utils.js"
|
||||||
const socket = io("/")
|
const socket = io("/")
|
||||||
const myPeer = new Peer()
|
const myPeer = new Peer()
|
||||||
const template = document.querySelector("#video-template")
|
const template = document.querySelector("#video-template")
|
||||||
const yourName = localStorage.getItem("name")
|
|
||||||
|
|
||||||
myPeer.on("open", async (id) => {
|
myPeer.on("open", async (id) => {
|
||||||
try {
|
try {
|
||||||
|
while (!localStorage.getItem("name")) {
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 2000))
|
||||||
|
}
|
||||||
|
const yourName = localStorage.getItem("name")
|
||||||
|
|
||||||
const stream = await navigator.mediaDevices.getUserMedia({
|
const stream = await navigator.mediaDevices.getUserMedia({
|
||||||
video: true,
|
video: true,
|
||||||
audio: true,
|
audio: true,
|
||||||
|
@ -28,13 +32,7 @@ myPeer.on("open", async (id) => {
|
||||||
connectToNewUser(userId, username, stream, myPeer)
|
connectToNewUser(userId, username, stream, myPeer)
|
||||||
)
|
)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (
|
if (error instanceof DOMException) return showNoVideoPrompt()
|
||||||
error.name == "NotAllowedError" ||
|
|
||||||
error.name == "NotFoundError" ||
|
|
||||||
error.name == "PermissionDeniedError" ||
|
|
||||||
error.name == "DevicesNotFoundError"
|
|
||||||
)
|
|
||||||
return showNoVideoPrompt()
|
|
||||||
|
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ body {
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
grid-auto-rows: 100vh;
|
grid-auto-rows: 100vh;
|
||||||
display: grid;
|
display: grid;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
#go {
|
#go {
|
||||||
|
@ -41,19 +42,27 @@ main {
|
||||||
background-color: var(--secondary);
|
background-color: var(--secondary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (min-width: 800px) {
|
||||||
|
#videos {
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(33%, 1fr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#videos {
|
#videos {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fit, minmax(33%, 1fr));
|
|
||||||
grid-template-rows: repeat(auto-fit, minmax(33%, 1fr));
|
grid-template-rows: repeat(auto-fit, minmax(33%, 1fr));
|
||||||
color: white;
|
color: white;
|
||||||
max-height: 100vh;
|
height: 100vh;
|
||||||
|
width: 100vw;
|
||||||
background-color: var(--secondary);
|
background-color: var(--secondary);
|
||||||
gap: 2px;
|
gap: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
video {
|
video {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
max-height: 100vh;
|
max-height: 100vh;
|
||||||
|
object-fit: cover;
|
||||||
}
|
}
|
||||||
|
|
||||||
.your-video {
|
.your-video {
|
||||||
|
@ -72,11 +81,12 @@ video {
|
||||||
}
|
}
|
||||||
|
|
||||||
.your-video .resizer {
|
.your-video .resizer {
|
||||||
width: 10px;
|
width: 15px;
|
||||||
height: 10px;
|
height: 15px;
|
||||||
background: var(--primary);
|
background: var(--primary);
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 0;
|
right: 0;
|
||||||
|
border-radius: 5px;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
cursor: se-resize;
|
cursor: se-resize;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,8 @@ app.use(express.static("public"))
|
||||||
|
|
||||||
app.get("/", (_, res) => res.render("index"))
|
app.get("/", (_, res) => res.render("index"))
|
||||||
|
|
||||||
|
app.get("/login", (_, res) => res.render("login"))
|
||||||
|
|
||||||
app.get("/:room", (req, res) => res.render("room", { roomId: req.params.room }))
|
app.get("/:room", (req, res) => res.render("room", { roomId: req.params.room }))
|
||||||
|
|
||||||
const users = {}
|
const users = {}
|
||||||
|
@ -25,12 +27,6 @@ io.on("connection", (socket) =>
|
||||||
})
|
})
|
||||||
|
|
||||||
socket.on("get-username", (userId, callback) => callback(users[userId]))
|
socket.on("get-username", (userId, callback) => callback(users[userId]))
|
||||||
|
|
||||||
socket.on("name-change", (name) => {
|
|
||||||
users[userId] = name
|
|
||||||
|
|
||||||
socket.to(roomId).emit("name-changed", userId)
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -6,31 +6,11 @@
|
||||||
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
|
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
|
||||||
<link rel="stylesheet" href="style.css" />
|
<link rel="stylesheet" href="style.css" />
|
||||||
<script src="/socket.io/socket.io.js" defer></script>
|
<script src="/socket.io/socket.io.js" defer></script>
|
||||||
<script src="scripts/login.js" defer></script>
|
|
||||||
<script src="scripts/goToRoom.js" type="module" defer></script>
|
<script src="scripts/goToRoom.js" type="module" defer></script>
|
||||||
|
<script src="scripts/login.js" defer></script>
|
||||||
<title>Video Chat</title>
|
<title>Video Chat</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="login" class="done">
|
|
||||||
<h1 class="large-header">Login</h1>
|
|
||||||
<div>
|
|
||||||
<input id="name-input" type="text" placeholder="Username" />
|
|
||||||
<button class="button-circle" id="name">
|
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
width="25"
|
|
||||||
height="25"
|
|
||||||
fill="currentColor"
|
|
||||||
class="bi bi-check-circle-fill"
|
|
||||||
viewBox="0 0 16 16"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zm-3.97-3.03a.75.75 0 0 0-1.08.022L7.477 9.417 5.384 7.323a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-.01-1.05z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="options" class="card">
|
<div id="options" class="card">
|
||||||
<div id="change-name">
|
<div id="change-name">
|
||||||
<span id="name-display"></span>
|
<span id="name-display"></span>
|
||||||
|
|
34
views/login.ejs
Normal file
34
views/login.ejs
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
|
||||||
|
<link rel="stylesheet" href="style.css" />
|
||||||
|
<script src="/socket.io/socket.io.js" defer></script>
|
||||||
|
<script src="scripts/login.js" defer></script>
|
||||||
|
<title>Video Chat</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="login">
|
||||||
|
<h1 class="large-header">Choose a name</h1>
|
||||||
|
<div>
|
||||||
|
<input id="name-input" type="text" placeholder="Username" />
|
||||||
|
<button class="button-circle" id="name">
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="25"
|
||||||
|
height="25"
|
||||||
|
fill="currentColor"
|
||||||
|
class="bi bi-check-circle-fill"
|
||||||
|
viewBox="0 0 16 16"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zm-3.97-3.03a.75.75 0 0 0-1.08.022L7.477 9.417 5.384 7.323a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-.01-1.05z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -19,26 +19,6 @@
|
||||||
<title>Video Chat</title>
|
<title>Video Chat</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="login" class="done">
|
|
||||||
<h1 class="large-header">Login</h1>
|
|
||||||
<div>
|
|
||||||
<input id="name-input" type="text" placeholder="Username" />
|
|
||||||
<button class="button-circle" id="name">
|
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
width="25"
|
|
||||||
height="25"
|
|
||||||
fill="currentColor"
|
|
||||||
class="bi bi-check-circle-fill"
|
|
||||||
viewBox="0 0 16 16"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zm-3.97-3.03a.75.75 0 0 0-1.08.022L7.477 9.417 5.384 7.323a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-.01-1.05z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="novideo">
|
<div id="novideo">
|
||||||
<h1 class="medium-header">No Video / Audio Device Found</h1>
|
<h1 class="medium-header">No Video / Audio Device Found</h1>
|
||||||
<div>
|
<div>
|
||||||
|
|
Reference in a new issue