forked from lavender/watch-party
165 lines
4.9 KiB
JavaScript
165 lines
4.9 KiB
JavaScript
var win = window;
|
|
var poppedOut = false;
|
|
|
|
const setupChatboxEvents = (socket) => {
|
|
// clear events by just reconstructing the form
|
|
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();
|
|
|
|
const input = chatForm.querySelector("input");
|
|
const content = input.value;
|
|
if (content.trim().length) {
|
|
input.value = "";
|
|
|
|
socket.send(
|
|
JSON.stringify({
|
|
op: "ChatMessage",
|
|
data: {
|
|
message: content,
|
|
},
|
|
})
|
|
);
|
|
}
|
|
});
|
|
};
|
|
|
|
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");
|
|
const chatboxContainer = document.querySelector("#chatbox-container");
|
|
|
|
if (video && chatbox && chatboxContainer) {
|
|
const delta = chatboxContainer.clientHeight - chatbox.clientHeight;
|
|
|
|
chatbox.style["height"] = `calc(${
|
|
window.innerHeight - video.clientHeight
|
|
}px - ${delta}px - 1em)`;
|
|
}
|
|
};
|
|
|
|
// 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) => {
|
|
win.document.querySelector("#chatbox-container").style["display"] = "block";
|
|
setupChatboxEvents(socket);
|
|
|
|
if (!poppedOut) {
|
|
fixChatSize();
|
|
window.addEventListener("resize", resizeCallback);
|
|
} else {
|
|
window.removeEventListener("resize", resizeCallback);
|
|
}
|
|
};
|
|
|
|
const printToChat = (elem) => {
|
|
const chatbox = win.document.querySelector("#chatbox");
|
|
chatbox.appendChild(elem);
|
|
chatbox.scrollTop = chatbox.scrollHeight;
|
|
};
|
|
|
|
export const handleChatEvent = (event) => {
|
|
switch (event.op) {
|
|
case "UserJoin": {
|
|
// print something to the chat
|
|
const chatMessage = win.document.createElement("div");
|
|
chatMessage.classList.add("chat-message");
|
|
chatMessage.classList.add("user-join");
|
|
const userName = win.document.createElement("strong");
|
|
userName.textContent = event.data;
|
|
chatMessage.appendChild(userName);
|
|
chatMessage.appendChild(win.document.createTextNode(" joined"));
|
|
printToChat(chatMessage);
|
|
break;
|
|
}
|
|
case "UserLeave": {
|
|
const chatMessage = win.document.createElement("div");
|
|
chatMessage.classList.add("chat-message");
|
|
chatMessage.classList.add("user-leave");
|
|
const userName = win.document.createElement("strong");
|
|
userName.textContent = event.data;
|
|
chatMessage.appendChild(userName);
|
|
chatMessage.appendChild(win.document.createTextNode(" left"));
|
|
printToChat(chatMessage);
|
|
break;
|
|
}
|
|
case "ChatMessage": {
|
|
const chatMessage = win.document.createElement("div");
|
|
chatMessage.classList.add("chat-message");
|
|
const userName = win.document.createElement("strong");
|
|
userName.innerText = event.data.user;
|
|
chatMessage.appendChild(userName);
|
|
chatMessage.appendChild(win.document.createTextNode(" "));
|
|
const messageContent = win.document.createElement("span");
|
|
messageContent.classList.add("message-content");
|
|
messageContent.textContent = event.data.message;
|
|
chatMessage.appendChild(messageContent);
|
|
printToChat(chatMessage);
|
|
break;
|
|
}
|
|
}
|
|
};
|