197 lines
4.2 KiB
JavaScript
197 lines
4.2 KiB
JavaScript
|
//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");
|
||
|
|
||
|
if (nickname != null) {
|
||
|
nickI.value = nickname;
|
||
|
}
|
||
|
|
||
|
//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";
|
||
|
|
||
|
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;
|
||
|
}
|
||
|
|
||
|
// Not Registered + Non error message means we have a new message!
|
||
|
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);
|
||
|
break;
|
||
|
case "leave":
|
||
|
userLeave(data.content, data.date);
|
||
|
break;
|
||
|
case "message":
|
||
|
chatMessage(data.sender, data.content, data.date)
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Join/leave events
|
||
|
*/
|
||
|
function userJoin(user, date) {
|
||
|
let p = document.createElement("p");
|
||
|
p.className = user;
|
||
|
p.innerText = user;
|
||
|
document.getElementById("users").appendChild(p);
|
||
|
serverMessage(data.content + " has joined the server", data.date);
|
||
|
}
|
||
|
|
||
|
function userLeave(user, date) {
|
||
|
users = document.getElementById("users");
|
||
|
users.removeChild(users.getElementsByClassName(user)[0]);
|
||
|
serverMessage(user + " has left the server", 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();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* 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;
|
||
|
}
|