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>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<title>watch party :D</title>
|
<title>watch party :D</title>
|
||||||
<link rel="stylesheet" href="/styles.css?v=2" />
|
<link rel="stylesheet" href="/styles.css?v=3" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
@ -43,10 +43,11 @@
|
||||||
<div id="chatbox-container">
|
<div id="chatbox-container">
|
||||||
<div id="chatbox"></div>
|
<div id="chatbox"></div>
|
||||||
<form id="chatbox-send">
|
<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>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script type="module" src="/main.mjs?v=1"></script>
|
<script type="module" src="/main.mjs?v=2"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -1,8 +1,14 @@
|
||||||
|
var win = window;
|
||||||
|
var poppedOut = false;
|
||||||
|
|
||||||
const setupChatboxEvents = (socket) => {
|
const setupChatboxEvents = (socket) => {
|
||||||
// clear events by just reconstructing the form
|
// 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);
|
const chatForm = oldChatForm.cloneNode(true);
|
||||||
oldChatForm.replaceWith(chatForm);
|
oldChatForm.replaceWith(chatForm);
|
||||||
|
if (!poppedOut) {
|
||||||
|
setupPopoutEvent(socket);
|
||||||
|
}
|
||||||
|
|
||||||
chatForm.addEventListener("submit", (e) => {
|
chatForm.addEventListener("submit", (e) => {
|
||||||
e.preventDefault();
|
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 fixChatSize = () => {
|
||||||
const video = document.querySelector("video");
|
const video = document.querySelector("video");
|
||||||
const chatbox = document.querySelector("#chatbox");
|
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
|
* @param {WebSocket} socket
|
||||||
*/
|
*/
|
||||||
export const setupChat = async (socket) => {
|
export const setupChat = async (socket) => {
|
||||||
document.querySelector("#chatbox-container").style["display"] = "block";
|
win.document.querySelector("#chatbox-container").style["display"] = "block";
|
||||||
setupChatboxEvents(socket);
|
setupChatboxEvents(socket);
|
||||||
|
|
||||||
fixChatSize();
|
if (!poppedOut) {
|
||||||
window.addEventListener("resize", () => {
|
|
||||||
fixChatSize();
|
fixChatSize();
|
||||||
});
|
window.addEventListener("resize", resizeCallback);
|
||||||
|
} else {
|
||||||
|
window.removeEventListener("resize", resizeCallback);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const printToChat = (elem) => {
|
const printToChat = (elem) => {
|
||||||
const chatbox = document.querySelector("#chatbox");
|
const chatbox = win.document.querySelector("#chatbox");
|
||||||
chatbox.appendChild(elem);
|
chatbox.appendChild(elem);
|
||||||
chatbox.scrollTop = chatbox.scrollHeight;
|
chatbox.scrollTop = chatbox.scrollHeight;
|
||||||
};
|
};
|
||||||
|
@ -61,37 +125,35 @@ export const handleChatEvent = (event) => {
|
||||||
switch (event.op) {
|
switch (event.op) {
|
||||||
case "UserJoin": {
|
case "UserJoin": {
|
||||||
// print something to the chat
|
// print something to the chat
|
||||||
const chatMessage = document.createElement("div");
|
const chatMessage = win.document.createElement("div");
|
||||||
chatMessage.classList.add("chat-message");
|
chatMessage.classList.add("chat-message");
|
||||||
chatMessage.classList.add("user-join");
|
chatMessage.classList.add("user-join");
|
||||||
const userName = document.createElement("strong");
|
const userName = win.document.createElement("strong");
|
||||||
userName.textContent = event.data;
|
userName.textContent = event.data;
|
||||||
chatMessage.appendChild(userName);
|
chatMessage.appendChild(userName);
|
||||||
chatMessage.appendChild(document.createTextNode(" joined"));
|
chatMessage.appendChild(win.document.createTextNode(" joined"));
|
||||||
printToChat(chatMessage);
|
printToChat(chatMessage);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "UserLeave": {
|
case "UserLeave": {
|
||||||
const chatMessage = document.createElement("div");
|
const chatMessage = win.document.createElement("div");
|
||||||
chatMessage.classList.add("chat-message");
|
chatMessage.classList.add("chat-message");
|
||||||
chatMessage.classList.add("user-leave");
|
chatMessage.classList.add("user-leave");
|
||||||
const userName = document.createElement("strong");
|
const userName = win.document.createElement("strong");
|
||||||
userName.textContent = event.data;
|
userName.textContent = event.data;
|
||||||
chatMessage.appendChild(userName);
|
chatMessage.appendChild(userName);
|
||||||
chatMessage.appendChild(document.createTextNode(" left"));
|
chatMessage.appendChild(win.document.createTextNode(" left"));
|
||||||
printToChat(chatMessage);
|
printToChat(chatMessage);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "ChatMessage": {
|
case "ChatMessage": {
|
||||||
const chatMessage = document.createElement("div");
|
const chatMessage = win.document.createElement("div");
|
||||||
chatMessage.classList.add("chat-message");
|
chatMessage.classList.add("chat-message");
|
||||||
const userName = document.createElement("strong");
|
const userName = win.document.createElement("strong");
|
||||||
userName.innerText = event.data.user;
|
userName.innerText = event.data.user;
|
||||||
chatMessage.appendChild(userName);
|
chatMessage.appendChild(userName);
|
||||||
chatMessage.appendChild(document.createTextNode(" "));
|
chatMessage.appendChild(win.document.createTextNode(" "));
|
||||||
const messageContent = document.createElement("span");
|
const messageContent = win.document.createElement("span");
|
||||||
messageContent.classList.add("message-content");
|
messageContent.classList.add("message-content");
|
||||||
messageContent.textContent = event.data.message;
|
messageContent.textContent = event.data.message;
|
||||||
chatMessage.appendChild(messageContent);
|
chatMessage.appendChild(messageContent);
|
||||||
|
|
|
@ -23,6 +23,7 @@ html {
|
||||||
html,
|
html,
|
||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
video {
|
video {
|
||||||
|
@ -67,7 +68,8 @@ input[type="text"] {
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
button {
|
button,
|
||||||
|
input[type="button"] {
|
||||||
background-color: var(--accent);
|
background-color: var(--accent);
|
||||||
border: var(--accent);
|
border: var(--accent);
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
|
@ -118,6 +120,15 @@ button.small-button {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#chatbox-container.popped-out {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#chatbox-container.popped-out > #chatbox {
|
||||||
|
height: calc(100vh - 5em);
|
||||||
|
}
|
||||||
|
|
||||||
.user-join,
|
.user-join,
|
||||||
.user-leave {
|
.user-leave {
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
|
@ -145,3 +156,12 @@ button.small-button {
|
||||||
#chatbox-send > input {
|
#chatbox-send > input {
|
||||||
font-size: 0.75em;
|
font-size: 0.75em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#message-box {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pop-chat {
|
||||||
|
width: auto;
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue