import { render, html } from '/uhtml.js'; import loadMessages from '/message.js'; import loadSpace from '/space.js'; function chooseThread() { if (window.currentThread) { if (window.currentThread.id === this.thread.id) return; document.getElementById(`thread${window.currentThread.id}`) .classList.remove('active'); } document.getElementById('threadname').textContent = this.thread.name; this.classList.add('active'); window.currentThread = this.thread; loadMessages(); if (this.thread.permissions.post) document.getElementById('msginput').classList.remove('hidden'); else document.getElementById('msginput').classList.add('hidden'); switchTab(document.getElementById(this.tab)); window.emit('get_thread', { thread: this.thread.id }, msg => { window.currentThread.members = msg.thread.members; document.getElementById('visibility').innerText = `${ msg.thread.permissions.everyone?.view.value === 'true' ? 'this thread is visible to everyone' : 'members can view this thread'} ${msg.thread.permissions.everyone?.post.value === 'true' ? 'anyone can post' : msg.thread.permissions.members?.post.view ? 'only members can post' : 'select members can post'}`; document.getElementById('memberlist').replaceChildren( ...msg.thread.members.map(member => html.node`

${member.name}

`) ); }); } function switchTab(tab) { for (let tab of document.querySelectorAll('.tab')) tab.classList.remove('active'); for (let tab of document.querySelectorAll('.tabcontent')) tab.classList.add('hidden'); tab.classList.add('active'); document .getElementById(tab.id.slice(0, -3)) .classList.remove('hidden'); if (tab.id === 'spacetab') loadSpace(); } function addMember() { const name = document.getElementById('membername').value; window.threadmembers.push(name); document .getElementById('newmembers') .appendChild(html.node`

${name}

`); document.getElementById('membername').value = ''; } async function createThread(event) { event.preventDefault(); let name = document.getElementById('newthreadname').value; if (!name) { document.getElementById('nameempty').classList.remove('hidden'); 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, permissions, members }, msg => { chooseThread.call(document.getElementById('thread' + msg.id)); // since the form exists, this will perform cleanup newThread(); document.getElementById('loadmore').classList.add('hidden'); } ); } function newThread() { let form = document.getElementById('createthread'); if (form) { form.remove(); document.getElementById('createseparator').remove(); document.getElementById('newthread').textContent = 'create'; } else { window.threadmembers = [window.name]; document.getElementById('home') .insertAdjacentElement('afterend', html.node`
`) .insertAdjacentElement('afterend', html.node`

create thread

thread permissions





{ if (event.key === 'Enter') { event.preventDefault(); addMember(); } }}/>

${window.name}


`); document.getElementById('newthread').textContent = 'cancel'; } } function clickedTab(event) { switchTab(event.target); document.getElementById(`thread${window.currentThread.id}`).tab = event.target.id; } // main app html document.body.append(html.node`

vybe

threads

loading...
document.getElementById('profile').classList.toggle('hidden') }>${window.name}


thread: meow

`); function makeThread(thread) { let node = html.node`
${ thread.name }
`; node.id = 'thread' + thread.id; node.thread = thread; node.tab = 'messagetab'; return node; } window.socket.on('new_thread', thread => { document.getElementById('threadlist').prepend(makeThread(thread)); }); window.emit('list_threads', {}, msg => { const threadlist = document.getElementById('threadlist'); threadlist.replaceChildren(...msg.threads.map(makeThread)); chooseThread.call(threadlist.firstChild); }); window.socket.on('authrequest', (msg, respond) => { const div = html.node`
session ${msg.id}
`; document.getElementById('authrequests').append(div); setTimeout(() => div.remove(), Date.now() - msg.time + 60000 * 5); });