gamja-old/assets/client.js

238 lines
5.2 KiB
JavaScript
Raw Normal View History

2020-04-24 13:01:02 -04:00
var server = {
name: "chat.freenode.net",
url: "ws://localhost:8080",
username: "soju-test-user/chat.freenode.net",
2020-04-24 13:01:02 -04:00
realname: "soju-test-user",
nick: "soju-test-user",
pass: "soju-test-user",
};
var buffers = {};
var activeBuffer = null;
var bufferListElt = document.querySelector("#buffer-list");
2020-04-25 06:51:35 -04:00
var bufferElt = document.querySelector("#buffer");
var composerElt = document.querySelector("#composer");
var composerInputElt = document.querySelector("#composer input");
2020-04-24 13:01:02 -04:00
2020-04-25 04:28:23 -04:00
function djb2(s) {
var hash = 5381;
for (var i = 0; i < s.length; i++) {
hash = (hash << 5) + hash + s.charCodeAt(i);
hash = hash >>> 0; // convert to uint32
}
return hash;
}
2020-04-25 17:00:49 -04:00
function createNickElement(name) {
var nick = document.createElement("a");
nick.href = "#";
nick.className = "nick nick-" + (djb2(name) % 16 + 1);
nick.innerText = name;
nick.onclick = function(event) {
event.preventDefault();
switchBuffer(createBuffer(name));
};
return nick;
}
2020-04-24 13:01:02 -04:00
function createMessageElement(msg) {
var date = new Date();
var line = document.createElement("div");
line.className = "logline";
var timestamp = document.createElement("a");
timestamp.href = "#";
timestamp.className = "timestamp";
timestamp.innerText = date.toLocaleTimeString(undefined, {
timeStyle: "short",
hour12: false,
});
timestamp.onclick = function(event) {
event.preventDefault();
};
line.appendChild(timestamp);
2020-04-25 14:20:39 -04:00
line.appendChild(document.createTextNode(" "));
2020-04-24 13:01:02 -04:00
switch (msg.command) {
case "NOTICE":
case "PRIVMSG":
var text = msg.params[1];
2020-04-25 14:20:39 -04:00
var actionPrefix = "\001ACTION ";
if (text.startsWith(actionPrefix) && text.endsWith("\001")) {
var action = text.slice(actionPrefix.length, -1);
line.className += " me-tell";
line.appendChild(document.createTextNode("* "));
2020-04-25 17:00:49 -04:00
line.appendChild(createNickElement(msg.prefix.name));
2020-04-25 14:20:39 -04:00
line.appendChild(document.createTextNode(" " + action));
} else {
line.className += " talk";
line.appendChild(document.createTextNode("<"));
2020-04-25 17:00:49 -04:00
line.appendChild(createNickElement(msg.prefix.name));
2020-04-25 14:20:39 -04:00
line.appendChild(document.createTextNode("> "));
line.appendChild(document.createTextNode(text));
}
2020-04-24 13:01:02 -04:00
break;
2020-04-25 17:00:49 -04:00
case "JOIN":
line.appendChild(createNickElement(msg.prefix.name));
line.appendChild(document.createTextNode(" has joined"));
break;
case "PART":
line.appendChild(createNickElement(msg.prefix.name));
line.appendChild(document.createTextNode(" has left"));
break;
2020-04-24 13:01:02 -04:00
default:
line.appendChild(document.createTextNode(" " + msg.command + " " + msg.params.join(" ")));
}
return line;
}
function createBuffer(name) {
if (buffers[name]) {
return buffers[name];
}
var a = document.createElement("a");
a.href = "#";
a.onclick = function(event) {
event.preventDefault();
switchBuffer(name);
};
a.innerText = name;
var li = document.createElement("li");
li.appendChild(a);
var buf = {
2020-04-24 13:01:02 -04:00
name: name,
li: li,
messages: [],
readOnly: false,
addMessage: function(msg) {
buf.messages.push(msg);
if (activeBuffer === buf) {
2020-04-25 06:51:35 -04:00
bufferElt.appendChild(createMessageElement(msg));
2020-04-24 13:01:02 -04:00
}
},
};
buffers[name] = buf;
bufferListElt.appendChild(li);
return buf;
}
function switchBuffer(buf) {
if (typeof buf == "string") {
buf = buffers[buf];
}
if (activeBuffer && buf === activeBuffer) {
return;
}
if (activeBuffer) {
activeBuffer.li.classList.remove("active");
}
activeBuffer = buf;
if (!buf) {
return;
}
buf.li.classList.add("active");
2020-04-25 06:51:35 -04:00
bufferElt.innerHTML = "";
2020-04-24 13:01:02 -04:00
for (var msg of buf.messages) {
2020-04-25 06:51:35 -04:00
bufferElt.appendChild(createMessageElement(msg));
2020-04-24 13:01:02 -04:00
}
composerElt.classList.toggle("read-only", buf.readOnly);
if (!buf.readOnly) {
composerInputElt.focus();
}
}
var serverBuffer = createBuffer(server.name);
serverBuffer.readOnly = true;
switchBuffer(serverBuffer);
var ws = new WebSocket(server.url);
ws.onopen = function() {
console.log("Connection opened");
if (server.pass) {
ws.send(formatMessage({ command: "PASS", params: [server.pass] }));
}
ws.send(formatMessage({ command: "NICK", params: [server.nick] }));
ws.send(formatMessage({
command: "USER",
params: [server.username, "0", "*", server.realname],
}));
};
ws.onmessage = function(event) {
var msg = parseMessage(event.data);
console.log(msg);
switch (msg.command) {
case "NOTICE":
case "PRIVMSG":
var target = msg.params[0];
if (target == server.nick) {
target = msg.prefix.name;
}
2020-04-25 08:59:20 -04:00
var buf;
if (target == "*") {
buf = serverBuffer;
} else {
buf = createBuffer(target);
}
buf.addMessage(msg);
2020-04-24 13:01:02 -04:00
break;
case "JOIN":
var channel = msg.params[0];
if (msg.prefix.name == server.nick) {
createBuffer(channel);
2020-04-25 17:00:49 -04:00
} else {
createBuffer(channel).addMessage(msg);
2020-04-24 13:01:02 -04:00
}
break;
2020-04-25 17:00:49 -04:00
case "PART":
var channel = msg.params[0];
createBuffer(channel).addMessage(msg);
break;
2020-04-24 13:01:02 -04:00
default:
serverBuffer.addMessage(msg);
}
};
ws.onclose = function() {
console.log("Connection closed");
};
composerElt.onsubmit = function(event) {
event.preventDefault();
if (!activeBuffer || activeBuffer.readOnly) {
return;
}
var target = activeBuffer.name;
var text = composerInputElt.value;
2020-04-25 04:33:52 -04:00
if (!text) {
return;
}
2020-04-24 13:01:02 -04:00
var msg = { command: "PRIVMSG", params: [target, text] };
ws.send(formatMessage(msg));
msg.prefix = { name: server.nick };
activeBuffer.addMessage(msg);
composerInputElt.value = "";
};