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 nameInput = document.querySelector("#name-input")
|
||||
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
|
||||
.querySelector("#change-name")
|
||||
.addEventListener("click", () => login.classList.remove("done"))
|
||||
?.addEventListener("click", () => (window.location = loginURL))
|
||||
|
||||
const yourName = localStorage.getItem("name")
|
||||
|
||||
if (yourName) nameDisplay.innerText = yourName
|
||||
else login.classList.remove("done")
|
||||
if (!yourName && window.location.pathname != "/login")
|
||||
window.location = loginURL
|
||||
if (yourName && nameDisplay) nameDisplay.innerText = yourName
|
||||
|
||||
const validate = () => {
|
||||
if (!nameInput.value) return (nameInput.required = true)
|
||||
document.querySelector("#login").classList.add("done")
|
||||
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)
|
||||
if (nameInput)
|
||||
nameInput.addEventListener(
|
||||
"keydown",
|
||||
(event) => event.keyCode == "13" && validate()
|
||||
)
|
||||
nameButton?.addEventListener?.("click", validate)
|
||||
nameInput?.addEventListener?.(
|
||||
"keydown",
|
||||
(event) => event.keyCode == "13" && validate()
|
||||
)
|
||||
|
|
|
@ -70,6 +70,8 @@ export const addVideoStream = (videoContainer, username, stream, isYours) => {
|
|||
|
||||
const video = videoContainer.querySelector("video")
|
||||
video.srcObject = stream
|
||||
if (CSS.supports("::-webkit-media-controls-panel"))
|
||||
video.controls = "controls"
|
||||
video.addEventListener("loadedmetadata", () => video.play())
|
||||
if (isYours) {
|
||||
video.muted = true
|
||||
|
|
|
@ -2,10 +2,14 @@ import { addVideoStream, connectToNewUser, showNoVideoPrompt } from "./utils.js"
|
|||
const socket = io("/")
|
||||
const myPeer = new Peer()
|
||||
const template = document.querySelector("#video-template")
|
||||
const yourName = localStorage.getItem("name")
|
||||
|
||||
myPeer.on("open", async (id) => {
|
||||
try {
|
||||
while (!localStorage.getItem("name")) {
|
||||
await new Promise((resolve) => setTimeout(resolve, 2000))
|
||||
}
|
||||
const yourName = localStorage.getItem("name")
|
||||
|
||||
const stream = await navigator.mediaDevices.getUserMedia({
|
||||
video: true,
|
||||
audio: true,
|
||||
|
@ -28,13 +32,7 @@ myPeer.on("open", async (id) => {
|
|||
connectToNewUser(userId, username, stream, myPeer)
|
||||
)
|
||||
} catch (error) {
|
||||
if (
|
||||
error.name == "NotAllowedError" ||
|
||||
error.name == "NotFoundError" ||
|
||||
error.name == "PermissionDeniedError" ||
|
||||
error.name == "DevicesNotFoundError"
|
||||
)
|
||||
return showNoVideoPrompt()
|
||||
if (error instanceof DOMException) return showNoVideoPrompt()
|
||||
|
||||
throw error
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ body {
|
|||
height: 100vh;
|
||||
grid-auto-rows: 100vh;
|
||||
display: grid;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#go {
|
||||
|
@ -41,19 +42,27 @@ main {
|
|||
background-color: var(--secondary);
|
||||
}
|
||||
|
||||
@media (min-width: 800px) {
|
||||
#videos {
|
||||
grid-template-columns: repeat(auto-fit, minmax(33%, 1fr));
|
||||
}
|
||||
}
|
||||
|
||||
#videos {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(33%, 1fr));
|
||||
grid-template-rows: repeat(auto-fit, minmax(33%, 1fr));
|
||||
color: white;
|
||||
max-height: 100vh;
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
background-color: var(--secondary);
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
video {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
max-height: 100vh;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.your-video {
|
||||
|
@ -72,11 +81,12 @@ video {
|
|||
}
|
||||
|
||||
.your-video .resizer {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
background: var(--primary);
|
||||
position: absolute;
|
||||
right: 0;
|
||||
border-radius: 5px;
|
||||
bottom: 0;
|
||||
cursor: se-resize;
|
||||
}
|
||||
|
|
|
@ -9,6 +9,8 @@ app.use(express.static("public"))
|
|||
|
||||
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 }))
|
||||
|
||||
const users = {}
|
||||
|
@ -25,12 +27,6 @@ io.on("connection", (socket) =>
|
|||
})
|
||||
|
||||
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" />
|
||||
<link rel="stylesheet" href="style.css" />
|
||||
<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/login.js" defer></script>
|
||||
<title>Video Chat</title>
|
||||
</head>
|
||||
<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="change-name">
|
||||
<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>
|
||||
</head>
|
||||
<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">
|
||||
<h1 class="medium-header">No Video / Audio Device Found</h1>
|
||||
<div>
|
||||
|
|
Reference in a new issue