diff --git a/frontend/chat.html b/frontend/chat.html new file mode 100644 index 0000000..7b32837 --- /dev/null +++ b/frontend/chat.html @@ -0,0 +1,22 @@ + + + + + watch party chat <3 + + + + + + +
+
+
+ +
+
+ + diff --git a/frontend/index.html b/frontend/index.html index e1c2e6b..53ac13c 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -3,7 +3,7 @@ watch party :D - + @@ -43,10 +43,11 @@
- + +
- + diff --git a/frontend/lib/chat.mjs b/frontend/lib/chat.mjs index 1a6ee1d..08f1a62 100644 --- a/frontend/lib/chat.mjs +++ b/frontend/lib/chat.mjs @@ -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); - fixChatSize(); - window.addEventListener("resize", () => { + if (!poppedOut) { 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); diff --git a/frontend/styles.css b/frontend/styles.css index 42240a8..021cbfd 100644 --- a/frontend/styles.css +++ b/frontend/styles.css @@ -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; +}