Add option to pop out the chat to a seperate window. #1
|
@ -0,0 +1,22 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>watch party chat <3</title>
|
||||
<link rel="stylesheet" href="/styles.css?v=3" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<noscript>
|
||||
This site will <em>not</em> work without JavaScript, and there's not
|
||||
really any way around that :(
|
||||
</noscript>
|
||||
|
||||
<div id="chatbox-container" class="popped-out">
|
||||
<div id="chatbox"></div>
|
||||
<form id="chatbox-send">
|
||||
<input type="text" placeholder="Message..." />
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -3,7 +3,7 @@
|
|||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>watch party :D</title>
|
||||
<link rel="stylesheet" href="/styles.css?v=2" />
|
||||
<link rel="stylesheet" href="/styles.css?v=3" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
@ -43,10 +43,11 @@
|
|||
<div id="chatbox-container">
|
||||
<div id="chatbox"></div>
|
||||
<form id="chatbox-send">
|
||||
<input type="text" placeholder="Message..." />
|
||||
<input type="text" id="message-box" placeholder="Message..." />
|
||||
<input type="button" id="pop-chat" value="Pop out chat" />
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<script type="module" src="/main.mjs?v=1"></script>
|
||||
<script type="module" src="/main.mjs?v=2"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,8 +1,14 @@
|
|||
var win = window;
|
||||
var poppedOut = false;
|
||||
|
||||
const setupChatboxEvents = (socket) => {
|
||||
// clear events by just reconstructing the form
|
||||
const oldChatForm = document.querySelector("#chatbox-send");
|
||||
const oldChatForm = win.document.querySelector("#chatbox-send");
|
||||
const chatForm = oldChatForm.cloneNode(true);
|
||||
oldChatForm.replaceWith(chatForm);
|
||||
if (!poppedOut) {
|
||||
setupPopoutEvent(socket);
|
||||
}
|
||||
|
||||
chatForm.addEventListener("submit", (e) => {
|
||||
e.preventDefault();
|
||||
|
@ -24,6 +30,13 @@ const setupChatboxEvents = (socket) => {
|
|||
});
|
||||
};
|
||||
|
||||
const setupPopoutEvent = (socket) => {
|
||||
const button = document.querySelector("#pop-chat");
|
||||
button.addEventListener("click", () => {
|
||||
openPopout(socket);
|
||||
});
|
||||
};
|
||||
|
||||
const fixChatSize = () => {
|
||||
const video = document.querySelector("video");
|
||||
const chatbox = document.querySelector("#chatbox");
|
||||
|
@ -38,21 +51,72 @@ const fixChatSize = () => {
|
|||
}
|
||||
};
|
||||
|
||||
// TODO: transfer chat history to popout and back?
|
||||
const openPopout = async (socket) => {
|
||||
win.document.querySelector("#chatbox-container").style["display"] = "none";
|
||||
const popout = window.open("/chat.html", "popout", "width=800,height=1000");
|
||||
win = popout;
|
||||
poppedOut = true;
|
||||
|
||||
// I am aware of the fact that this is incredibly cursed,
|
||||
// but apparently this is the only way to wait for a child window to load....
|
||||
// I love browsers :)
|
||||
function defer(callback) {
|
||||
var channel = new MessageChannel();
|
||||
channel.port1.onmessage = function (e) {
|
||||
callback();
|
||||
};
|
||||
channel.port2.postMessage(null);
|
||||
}
|
||||
|
||||
win.addEventListener("unload", () => {
|
||||
defer(() => {
|
||||
if (popout.document.readyState === "complete") {
|
||||
setupChat(socket);
|
||||
// pop the chat back into the parent window on close
|
||||
win.addEventListener("unload", () => {
|
||||
popBackChat(socket);
|
||||
});
|
||||
} else {
|
||||
win.document.addEventListener("DOMContentLoaded", () => {
|
||||
setupChat(socket);
|
||||
// pop the chat back into the parent window on close
|
||||
win.addEventListener("unload", () => {
|
||||
popBackChat(socket);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const popBackChat = async (socket) => {
|
||||
win = window;
|
||||
poppedOut = false;
|
||||
setupChat(socket);
|
||||
};
|
||||
|
||||
const resizeCallback = () => {
|
||||
fixChatSize();
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {WebSocket} socket
|
||||
*/
|
||||
export const setupChat = async (socket) => {
|
||||
document.querySelector("#chatbox-container").style["display"] = "block";
|
||||
win.document.querySelector("#chatbox-container").style["display"] = "block";
|
||||
setupChatboxEvents(socket);
|
||||
|
||||
if (!poppedOut) {
|
||||
fixChatSize();
|
||||
window.addEventListener("resize", () => {
|
||||
fixChatSize();
|
||||
});
|
||||
window.addEventListener("resize", resizeCallback);
|
||||
} else {
|
||||
window.removeEventListener("resize", resizeCallback);
|
||||
}
|
||||
};
|
||||
|
||||
const printToChat = (elem) => {
|
||||
const chatbox = document.querySelector("#chatbox");
|
||||
const chatbox = win.document.querySelector("#chatbox");
|
||||
chatbox.appendChild(elem);
|
||||
chatbox.scrollTop = chatbox.scrollHeight;
|
||||
};
|
||||
|
@ -61,37 +125,35 @@ export const handleChatEvent = (event) => {
|
|||
switch (event.op) {
|
||||
case "UserJoin": {
|
||||
// print something to the chat
|
||||
const chatMessage = document.createElement("div");
|
||||
const chatMessage = win.document.createElement("div");
|
||||
chatMessage.classList.add("chat-message");
|
||||
chatMessage.classList.add("user-join");
|
||||
const userName = document.createElement("strong");
|
||||
const userName = win.document.createElement("strong");
|
||||
userName.textContent = event.data;
|
||||
chatMessage.appendChild(userName);
|
||||
chatMessage.appendChild(document.createTextNode(" joined"));
|
||||
chatMessage.appendChild(win.document.createTextNode(" joined"));
|
||||
printToChat(chatMessage);
|
||||
|
||||
break;
|
||||
}
|
||||
case "UserLeave": {
|
||||
const chatMessage = document.createElement("div");
|
||||
const chatMessage = win.document.createElement("div");
|
||||
chatMessage.classList.add("chat-message");
|
||||
chatMessage.classList.add("user-leave");
|
||||
const userName = document.createElement("strong");
|
||||
const userName = win.document.createElement("strong");
|
||||
userName.textContent = event.data;
|
||||
chatMessage.appendChild(userName);
|
||||
chatMessage.appendChild(document.createTextNode(" left"));
|
||||
chatMessage.appendChild(win.document.createTextNode(" left"));
|
||||
printToChat(chatMessage);
|
||||
|
||||
break;
|
||||
}
|
||||
case "ChatMessage": {
|
||||
const chatMessage = document.createElement("div");
|
||||
const chatMessage = win.document.createElement("div");
|
||||
chatMessage.classList.add("chat-message");
|
||||
const userName = document.createElement("strong");
|
||||
const userName = win.document.createElement("strong");
|
||||
userName.innerText = event.data.user;
|
||||
chatMessage.appendChild(userName);
|
||||
chatMessage.appendChild(document.createTextNode(" "));
|
||||
const messageContent = document.createElement("span");
|
||||
chatMessage.appendChild(win.document.createTextNode(" "));
|
||||
const messageContent = win.document.createElement("span");
|
||||
messageContent.classList.add("message-content");
|
||||
messageContent.textContent = event.data.message;
|
||||
chatMessage.appendChild(messageContent);
|
||||
|
|
|
@ -23,6 +23,7 @@ html {
|
|||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
video {
|
||||
|
@ -67,7 +68,8 @@ input[type="text"] {
|
|||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
button {
|
||||
button,
|
||||
input[type="button"] {
|
||||
background-color: var(--accent);
|
||||
border: var(--accent);
|
||||
border-radius: 6px;
|
||||
|
@ -118,6 +120,15 @@ button.small-button {
|
|||
display: none;
|
||||
}
|
||||
|
||||
#chatbox-container.popped-out {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#chatbox-container.popped-out > #chatbox {
|
||||
height: calc(100vh - 5em);
|
||||
}
|
||||
|
||||
.user-join,
|
||||
.user-leave {
|
||||
font-style: italic;
|
||||
|
@ -145,3 +156,12 @@ button.small-button {
|
|||
#chatbox-send > input {
|
||||
font-size: 0.75em;
|
||||
}
|
||||
|
||||
#message-box {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#pop-chat {
|
||||
width: auto;
|
||||
float: right;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue