vybe/client/chat.js

167 lines
5.1 KiB
JavaScript
Raw Normal View History

2023-05-07 18:43:57 -07:00
function rand() {
2023-05-15 17:19:24 -07:00
let str = "";
const lookups =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".split("");
while (str.length < 16) {
const n = Math.random() * lookups.length;
str += lookups[Math.floor(n)];
}
return str;
2023-05-07 18:43:57 -07:00
}
async function auth() {
2023-05-15 17:19:24 -07:00
let session = rand();
const sig = await openpgp.sign({
message: new openpgp.CleartextMessage("vybe_auth " + session, ""),
signingKeys: window.keys.priv,
});
window.session = session;
window.socket.emit("authenticate", { name: window.name, message: sig });
2023-05-08 21:02:57 -07:00
}
2023-05-15 18:05:47 -07:00
async function loadKeys(keys) {
const priv = await openpgp.readKey({ armoredKey: keys.privateKey });
const pub = await openpgp.readKey({ armoredKey: keys.publicKey });
window.keys = { priv, pub };
await auth();
}
2023-05-08 21:02:57 -07:00
function chooseThread(thread) {
2023-05-15 17:19:24 -07:00
window.currentThreadId = thread.id;
window.earliestMessage = null;
document.getElementById("loadmore").classList.remove("hidden");
document.getElementById("messages").innerHTML = "";
document.getElementById("threadname").innerHTML = thread.name;
2023-05-08 21:02:57 -07:00
}
2023-05-15 18:05:47 -07:00
function loadMessages() {
window.socket.emit(
"get_history",
{ before: window.earliestMessage, thread: window.currentThreadId }
);
}
function addThread(thread) {
const el = document.createElement("div");
el.classList.add("thread");
el.innerHTML = thread.name;
const btn = document.createElement("button");
btn.innerHTML = "choose";
btn.onclick = () => {
chooseThread(thread);
loadMessages();
};
el.appendChild(btn);
document.getElementById("threadlist").appendChild(el);
2023-05-05 21:56:59 -07:00
}
2023-05-05 20:12:07 -07:00
window.onload = () => {
2023-05-15 17:19:24 -07:00
window.currentThreadId = 1;
window.socket = io();
window.socket.on("create_user", auth);
window.socket.on("new_message", (msg) => {
if (msg.thread !== window.currentThreadId) return;
const el = document.createElement("div");
el.classList.add("message");
const strong = document.createElement('strong');
strong.textContent = msg.name + ': ';
el.append(strong, msg.message);
document.getElementById("messages").appendChild(el);
if (!window.earliestMessage) window.earliestMessage = msg.id;
});
window.socket.on("send_message", (msg) => {
if (!window.earliestMessage) window.earliestMessage = msg.id;
});
window.socket.on("get_history", (msg) => {
if (msg.messages.length > 0) {
window.earliestMessage = msg.messages[msg.messages.length - 1].id;
for (let message of msg.messages) {
const el = document.createElement("div");
el.classList.add("message");
const strong = document.createElement('strong');
strong.textContent = message.name + ': ';
el.append(strong, message.message);
document.getElementById("messages").prepend(el);
}
}
if (!msg.more) document.getElementById("loadmore").classList.add("hidden");
});
window.socket.on("authenticate", (msg) => {
if (msg.success) {
document.getElementById("register").classList.add("hidden");
document.getElementById("threads").classList.remove("hidden");
document.getElementById("chat").classList.remove("hidden");
window.socket.emit("list_threads");
}
let emitter = window.socket.emit;
window.socket.emit = (type, data) => {
if (data)
return emitter.call(window.socket, type, {
...data,
__session: window.session,
});
else return emitter.call(window.socket, type);
};
});
window.socket.on("list_threads", (msg) => {
document.getElementById("threadlist").innerHTML = "";
for (let thread of msg.threads)
addThread(thread);
});
window.socket.on('new_thread', addThread);
window.socket.on("create_thread", (msg) => {
chooseThread({
name: document.getElementById("newthreadname").value,
id: msg.id,
});
document.getElementById("newthreadname").value = "";
});
document.getElementById("registerform").onsubmit = async e => {
e.preventDefault();
const name = document.getElementById("name").value;
if (!name) return;
const keys = await openpgp.generateKey({
userIDs: [{ name }],
});
const priv = await openpgp.readKey({ armoredKey: keys.privateKey });
const pub = await openpgp.readKey({ armoredKey: keys.publicKey });
window.keys = { priv, pub };
localStorage.setItem("keys", JSON.stringify(keys));
localStorage.setItem("name", name);
window.name = name;
window.socket.emit("create_user", { name, pubkey: keys.publicKey });
};
document.getElementById("msginput").onsubmit = e => {
e.preventDefault();
const msg = document.getElementById("msg").value;
if (!msg) return;
window.socket.emit("send_message", {
message: msg,
thread: window.currentThreadId,
});
document.getElementById("msg").value = "";
const el = document.createElement("div");
el.classList.add("message");
el.innerHTML = `<strong>${window.name}: </strong>${msg}`;
document.getElementById("messages").appendChild(el);
};
document.getElementById("loadmore").onclick = e => {
2023-05-15 18:05:47 -07:00
loadMessages();
2023-05-15 17:19:24 -07:00
};
document.getElementById("createthread").onsubmit = e => {
e.preventDefault();
window.socket.emit("create_thread", {
name: document.getElementById("newthreadname").value,
});
};
const keys = localStorage.getItem("keys");
if (keys) {
window.name = localStorage.getItem("name");
loadKeys(JSON.parse(keys)).then(() => {});
}
else
document.getElementById("register").classList.remove("hidden");
2023-05-05 20:12:07 -07:00
};