//Saved nickname from previous usage let nickname = window.localStorage.getItem("nickname"); //Nickname button and input let nickI = document.getElementById("nickI"); let nickB = document.getElementById("nickB"); //Chatting button and input let chatI = document.getElementById("chatI"); let chatB = document.getElementById("chatB"); let registered = false; let modal = document.getElementById("modal"); //Gets websocket url by replacing http with ws and https with wss, and appending /websocket to the host let protocol = location.protocol == "http:" ? "ws:" : "wss:"; let url = protocol + "//" + location.host + "/websocket"; if (nickname != null) { nickI.value = nickname; } let ws = new WebSocket(url); ws.onopen = function() { modal.style.display = "block"; nickI.focus(); } ws.onmessage = function(info) { let data = JSON.parse(info.data); if(!data.success) { toast("Error: " + data.content); return; } if (!registered) { registered = true; window.localStorage.setItem("nickname", nickname); modal.style.display = "none"; chatI.focus() let users = data.content; for(let i = 0; i < users.length; i++) { userJoin(users[i]); } return; } newMessage(data); } /* * Message receive handling */ function newMessage(data) { switch(data.type) { case "join": userJoin(data.content, data.date); serverMessage(data.content + " has joined the server", data.date); break; case "leave": userLeave(data.content, data.date); break; case "message": chatMessage(data.sender, data.content, data.date) } } function chatMessage(sender, content, date) { let msg = create("div", "message"); aClasses = "author" if (sender === nickname) { aClasses += " self" } let author = create("div", aClasses); author.innerText = sender; let timestamp = create("div", "timestamp"); timestamp.innerText = dateToString(new Date(date)); let text = create("div", "content"); text.innerText = content; msg.append(author, timestamp, text); insertMessage(msg); } function serverMessage(content, date) { let msg = create("div", "message"); let text = create("div", "server-message"); text.innerText = content; msg.append(text); insertMessage(msg); } function insertMessage(div) { //If message scrolling at the bottom, move to bottom again to update let scroller = document.getElementsByClassName("messages")[0]; let currentScroll = scroller.scrollTop; let maxScroll = scroller.scrollHeight - scroller.clientHeight; document.getElementById("messages").append(div); if (currentScroll === maxScroll) { div.scrollIntoView(); } } /** * Join/leave events */ function userJoin(user, date) { let p = document.createElement("p"); p.className = user; p.innerText = user; document.getElementById("users").appendChild(p); } function userLeave(user, date) { users = document.getElementById("users"); users.removeChild(users.getElementsByClassName(user)[0]); serverMessage(user + " has left the server", date); } /* * Registration */ function register() { let nick = nickI.value; if (nick.trim().length == 0) return; nickname = nick; ws.send(nick); } nickI.onkeydown = function(ev) { if(ev.key !== "Enter") { return; } register(); } nickB.onclick = function() { register(); } /** * Message sending */ chatI.onkeydown = function(ev) { if(ev.key !== "Enter") { return; } if(chatI.value.trim().length == 0) return; ws.send(chatI.value); chatI.value = ""; } chatB.onclick = function() { if(chatI.value.trim().length == 0) return; ws.send(chatI.value); chatI.value = ""; } /* * Util functions */ function toast(message) { var x = document.getElementById("snackbar"); x.innerText = message; x.className = "snackshow"; setTimeout(function(){ x.className = x.className.replace("snackshow", ""); }, 3000); } let months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] function dateToString(date) { let year = date.getFullYear(); let month = months[date.getMonth()]; let day = date.getDate(); let hour = date.getHours(); let minute = date.getMinutes(); return ` ${day} ${month} ${year} at ${hour}:${minute}`; } function create(name, classes) { let x = document.createElement(name); x.className = classes; return x; }