import { render, html } from '/uhtml.js'; window.currentThreadId = 1; function chooseThread(thread) { if (window.currentThreadId) document .getElementById(`thread${window.currentThreadId}`) .classList.remove("active"); document.getElementById(`thread${thread.id}`).classList.add("active"); window.currentThreadId = thread.id; window.earliestMessage = null; document.getElementById("messages").innerHTML = ""; document.getElementById("threadname").textContent = thread.name; if (!thread.permissions.post) { document.getElementById("msginput").classList.add("hidden"); } else { document.getElementById("msginput").classList.remove("hidden"); } loadMessages(); } function loadMessages() { window.emit( "get_history", { before: window.earliestMessage, thread: window.currentThreadId, }, msg => { if (msg.messages.length > 0) { window.earliestMessage = msg.messages[msg.messages.length - 1].id; for (let message of msg.messages) document.getElementById("messages").prepend(html.node`
`); } if (!msg.more) document.getElementById("loadmore").classList.add("hidden"); else document.getElementById("loadmore").classList.remove("hidden"); } ); } function addThread(thread, top) { let node = html.node`${name}
`); document.getElementById("membername").value = ""; } async function createThread(e) { e.preventDefault(); let name = document.getElementById("newthreadname"); if (!name.value) { name.insertAdjacentHTML('afterend', `name cannot be empty
`); return; } let members = window.threadmembers.map(name => ({ name })); const perms = document.querySelector( 'input[name="permissions"]:checked' ).value; if (perms === "private_view") members = ( await new Promise(resolve => window.emit("get_keys", { names: window.threadmembers }, resolve) ) ).keys; let permissions; if (perms === "public") { permissions = { view_limited: false, post_limited: false }; } else if (perms === "private_post") { permissions = { view_limited: false, post_limited: true }; } else if (perms === "private_view") { permissions = { view_limited: true, post_limited: true }; // generate key /* wip var buf = new Uint8Array(32); crypto.getRandomValues(buf); const key = aesjs.utils.hex.fromBytes(Array.from(buf)); // sign it to each of the members for (let i = 0; i < newmembers.length; i++) { const member = newmembers[i]; const sig = await openpgp.encrypt({ message: await openpgp.createMessage({ text: key }), signingKeys: window.keys.priv, }); } */ } window.emit( "create_thread", { name: name.value, permissions, members, }, msg => { chooseThread({ name: name.value, id: msg.id, }); // since the form exists, this will perform cleanup newThread(); document.getElementById("loadmore").classList.add("hidden"); document.getElementById("msginput").classList.remove("hidden"); } ); } function sendMessage(e) { e.preventDefault(); const msg = document.getElementById("msg").value; if (!msg) return; window.emit("send_message", { message: msg, thread: window.currentThreadId }); document.getElementById("msg").value = ""; } function newThread() { let form = document.getElementById('createthread'); if (form) { form.remove(); document.getElementById("newthread").textContent = 'create'; } else { window.threadmembers = [window.name]; document.getElementById('threads').insertAdjacentElement('afterend', html.node` ` ); document.getElementById("newthread").textContent = 'cancel'; } } function switchTab(event) { for (let tab of document.querySelectorAll('.tab')) tab.classList.remove('active'); for (let tab of document.querySelectorAll('.tabcontent')) tab.classList.add('hidden'); event.target.classList.add('active'); document .getElementById(event.target.id.substring(0, event.target.id.length - 3)) .classList.remove('hidden'); } render(document.body, html`