instance pane
							parent
							
								
									02294b0327
								
							
						
					
					
						commit
						b8b7a7edd6
					
				|  | @ -94,7 +94,26 @@ function expandInstance(event) { | |||
| 	this.children[0].classList.toggle('collapsed'); | ||||
| } | ||||
| 
 | ||||
| function instanceClicked(event) {} | ||||
| function instanceClicked(event) { | ||||
| 	let instance = this.parentElement.parentElement.instance; | ||||
| 	let div = document.getElementById('instance'); | ||||
| 	if (div.classList.contains('hidden')) { | ||||
| 		let disconnect = document.getElementById('disconnect'); | ||||
| 		if (window.instancelist[0] === instance) | ||||
| 			disconnect.classList.add('hidden'); | ||||
| 		else | ||||
| 			disconnect.classList.remove('hidden'); | ||||
| 		document.getElementById('instancename').textContent = instance.url; | ||||
| 		let userlist = document.getElementById('userlist'); | ||||
| 		userlist.innerHTML = ''; | ||||
| 		instance.emit('list_users', {}, msg => | ||||
| 			userlist.innerHTML = msg.users.map(user => | ||||
| 				`<p>${user.displayname}</p>`).join('\n') | ||||
| 		); | ||||
| 		div.instance = instance; | ||||
| 	} | ||||
| 	div.classList.toggle('hidden'); | ||||
| } | ||||
| 
 | ||||
| function saveInstances() { | ||||
| 	localStorage.setItem('instances', JSON.stringify( | ||||
|  | @ -110,10 +129,9 @@ async function addInstance() { | |||
| 	let instancediv = this.parentElement.parentElement; | ||||
| 	if (!this.textContent) | ||||
| 		return instancediv.remove(); | ||||
| 	let url = (/^[\w-]+:.+/.test(this.textContent) ? '' : 'https://') + this.textContent; | ||||
| 	if (window.instancelist.find(i => i.url === url)) | ||||
| 	if (window.instancelist.find(i => i.url === this.textContent)) | ||||
| 		return instancediv.remove(); | ||||
| 	let instance = await connectInstance(url); | ||||
| 	let instance = await connectInstance(this.textContent); | ||||
| 	instancediv.instance = instance; | ||||
| 	await authenticateInstance(instancediv, true); | ||||
| 	this.contentEditable = false; | ||||
|  | @ -130,13 +148,29 @@ async function addInstance() { | |||
| 
 | ||||
| // main app html
 | ||||
| document.body.append(html.node` | ||||
| 	<div id='profile' class='column hidden'> | ||||
| 		<p><strong>profile</strong></p> | ||||
| 		<label class='heading'>display name</label> | ||||
| 		<input id='newname' onkeyup=${function(event) { | ||||
| 			if (window.displayname === this.value) | ||||
| 				document.getElementById('savename').classList.add('hidden'); | ||||
| 			else if (event.key === 'Enter') | ||||
| 				changeName(); | ||||
| 			else | ||||
| 				document.getElementById('savename').classList.remove('hidden'); | ||||
| 		}}> | ||||
| 		<button class='hidden' id='savename' onclick=${changeName}>save</button> | ||||
| 		<label class='heading'>authentication requests</label> | ||||
| 		<div id='authrequests'></div> | ||||
| 	</div> | ||||
| 	<hr class='separator' color='#505050'> | ||||
| 	<div id='home' class='column'> | ||||
| 		<div id='instancelist'> | ||||
| 			<h3>vybe</h3> | ||||
| 			<p id='instances'>instances:<button onclick=${() => { | ||||
| 				let div = html.node` | ||||
| 					<div> | ||||
| 						<div class='instance'> | ||||
| 						<div class='instancetitle'> | ||||
| 							<span> </span> | ||||
| 							<span onblur=${addInstance} onkeydown=${function(event) { | ||||
| 								if (event.key === 'Enter') { | ||||
|  | @ -156,31 +190,30 @@ document.body.append(html.node` | |||
| 		}>${window.name}</div> | ||||
| 	</div> | ||||
| 	<hr class='separator' color='#505050'> | ||||
| 	<!-- create thread column goes here --> | ||||
| 	<hr class='separator' color='#505050'> | ||||
| 	<div id='profile' class='column hidden'> | ||||
| 		<p><strong>profile</strong></p> | ||||
| 		<label class='heading'>display name</label> | ||||
| 		<input id='newname' onkeyup=${function(event) { | ||||
| 			if (window.displayname === this.value) | ||||
| 				document.getElementById('savename').classList.add('hidden'); | ||||
| 			else if (event.key === 'Enter') | ||||
| 				changeName(); | ||||
| 			else | ||||
| 				document.getElementById('savename').classList.remove('hidden'); | ||||
| 		}}> | ||||
| 		<button class='hidden' id='savename' onclick=${changeName}>save</button> | ||||
| 		<label class='heading'>authentication requests</label> | ||||
| 		<div id='authrequests'></div> | ||||
| 	<div id='instance' class='column hidden'> | ||||
| 		<div class='content'> | ||||
| 			<p>instance: <strong id='instancename'></strong></p> | ||||
| 			<h4>users</h4> | ||||
| 			<div id='userlist'> | ||||
| 			</div> | ||||
| 		</div> | ||||
| 		<button id='disconnect' onclick=${function(event) { | ||||
| 			document.getElementById('instance' + this.parentElement.instance.id).remove(); | ||||
| 			window.instancelist.splice(window.instancelist.indexOf(this.parentElement.instance), 1); | ||||
| 			saveInstances(); | ||||
| 			document.getElementById('instance').classList.add('hidden'); | ||||
| 		}}>disconnect</button> | ||||
| 	</div> | ||||
| 	<hr class='separator' color='#505050'> | ||||
| 	<!-- create thread column goes here --> | ||||
| 	<hr class='separator' color='#505050'> | ||||
| `);
 | ||||
| 
 | ||||
| for (let i = 0; i < instancelist.length; ++i) { | ||||
| 	let instance = instancelist[i]; | ||||
| 	let div = html.node` | ||||
| 		<div> | ||||
| 			<div class='instance'> | ||||
| 			<div class='instancetitle'> | ||||
| 				<span class='expander' onclick=${expandInstance}> | ||||
| 					<span class='arrow'>◿</span> | ||||
| 				</span> | ||||
|  |  | |||
|  | @ -71,11 +71,12 @@ | |||
| 				max-width: 800px; | ||||
| 			} | ||||
| 			:not(#register) > p { | ||||
| 				margin: 5px 1px; | ||||
| 				margin-block: 5px; | ||||
| 				word-wrap: break-word; | ||||
| 			} | ||||
| 			.thread:hover, | ||||
| 			.tab:hover, | ||||
| 			.instance > span:hover, | ||||
| 			.instancetitle > span:hover, | ||||
| 			#user:hover { | ||||
| 				background-color: #333; | ||||
| 			} | ||||
|  | @ -86,7 +87,7 @@ | |||
| 				color: #fff; | ||||
| 			} | ||||
| 			label.heading { | ||||
| 				margin: 10px 1px 4px; | ||||
| 				margin: 10px 0 4px; | ||||
| 				display: block; | ||||
| 			} | ||||
| 			h3 { | ||||
|  | @ -106,18 +107,22 @@ | |||
| 				margin: 8px 2px; | ||||
| 			} | ||||
| 			.separator:has(+ .separator), | ||||
| 			*.hidden + .separator, | ||||
| 			.separator:has(+ *.hidden), | ||||
| 			.separator:last-child { | ||||
| 				display: none; | ||||
| 			} | ||||
| 			.instance { | ||||
| 			.content { | ||||
| 				flex: 1; | ||||
| 			} | ||||
| 			.instancetitle { | ||||
| 				margin: 2px; | ||||
| 				> span { | ||||
| 					display: table-cell; | ||||
| 					background-color: #222; | ||||
| 					padding-block: 6px; | ||||
| 				} | ||||
| 				> .title { | ||||
| 					padding-block: 6px; | ||||
| 					width: 100%; | ||||
| 				} | ||||
| 			} | ||||
|  | @ -142,8 +147,11 @@ | |||
| 				flex-direction: column; | ||||
| 				justify-content: space-between; | ||||
| 			} | ||||
| 			#instancelist > :not(div) { | ||||
| 				margin: 3px; | ||||
| 			#instancelist { | ||||
| 				overflow-y: auto; | ||||
| 				> :not(div) { | ||||
| 					margin: 3px; | ||||
| 				} | ||||
| 			} | ||||
| 			#instances { | ||||
| 				display: flex; | ||||
|  | @ -166,6 +174,15 @@ | |||
| 			#profile { | ||||
| 				max-width: 250px; | ||||
| 			} | ||||
| 			#instance { | ||||
| 				display: flex; | ||||
| 				flex-direction: column; | ||||
| 				justify-content: space-between; | ||||
| 				max-width: 250px; | ||||
| 			} | ||||
| 			#disconnect { | ||||
| 				width: fit-content; | ||||
| 			} | ||||
| 			.thread { | ||||
| 				padding: 2px 3px; | ||||
| 				white-space: pre; | ||||
|  | @ -187,7 +204,7 @@ | |||
| 			} | ||||
| 			#content { | ||||
| 				margin: 2px; | ||||
| 				flex: 1; | ||||
| 				min-width: 300px; | ||||
| 				display: flex; | ||||
| 				flex-direction: column; | ||||
| 			} | ||||
|  | @ -237,11 +254,8 @@ | |||
| 				margin-bottom: 10px; | ||||
| 			} | ||||
| 			#members { | ||||
| 				flex: 1; | ||||
| 				min-width: 140px; | ||||
| 				max-width: 250px; | ||||
| 				> * { | ||||
| 					margin: 4px; | ||||
| 				} | ||||
| 			} | ||||
| 			#editthread { | ||||
| 				max-width: fit-content; | ||||
|  |  | |||
|  | @ -129,7 +129,7 @@ function newThread() { | |||
| 		name.value = ''; | ||||
| 	} | ||||
| 
 | ||||
| 	document.querySelector('#home + .separator').insertAdjacentElement('afterend', html.node` | ||||
| 	document.querySelector('#instance + .separator').insertAdjacentElement('afterend', html.node` | ||||
| 		<form id='createthread' class='column' onsubmit=${event => { | ||||
| 			event.preventDefault(); | ||||
| 			let name = document.getElementById('newthreadname').value; | ||||
|  | @ -164,7 +164,7 @@ function newThread() { | |||
| 				} | ||||
| 			); | ||||
| 		}}> | ||||
| 			<h3>create thread</h3> | ||||
| 			<h4>create thread</h4> | ||||
| 			<label for='newthreadname' class='heading'>thread name</label> | ||||
| 			<p id='newnameempty' class='hidden'>name cannot be empty</p> | ||||
| 			<input type='text' id='newthreadname' /> | ||||
|  | @ -237,6 +237,7 @@ function editThread() { | |||
| 					editThread(); | ||||
| 				}); | ||||
| 		}}> | ||||
| 			<h4>edit thread</h4> | ||||
| 			<label for='editthreadname' class='heading'>thread name</label> | ||||
| 			<input type='text' id='editthreadname' /> | ||||
| 			<p id='nameempty' class='hidden'>name cannot be empty</p> | ||||
|  | @ -260,7 +261,7 @@ function editThread() { | |||
| 		form['private_post'].checked = true; | ||||
| 	else | ||||
| 		form['private_view'].checked = true; | ||||
| 	document.querySelector('#thread').append(form); | ||||
| 	document.body.append(form); | ||||
| 	document.getElementById('edit').textContent = 'cancel'; | ||||
| } | ||||
| 
 | ||||
|  | @ -289,7 +290,7 @@ async function loadThreads(instancediv, select) { | |||
| 	if (!document.getElementById('thread')) | ||||
| 		document.body.append(html.node` | ||||
| 			<div id='thread' class='column hidden'> | ||||
| 				<div id='content'> | ||||
| 				<div id='content' class='content'> | ||||
| 					<div id='titlebar'> | ||||
| 						<span id='title'>thread: <strong id='threadname'>meow</strong></span> | ||||
| 						<button id='edit' class='hidden' onclick=${editThread}>edit</button> | ||||
|  | @ -309,14 +310,14 @@ async function loadThreads(instancediv, select) { | |||
| 					<div id='stream' class='tabcontent hidden'></div> | ||||
| 				</div> | ||||
| 				<hr class='separator' color='#505050'> | ||||
| 				<div id='members' class='hidden'> | ||||
| 				<div id='members' class='column hidden'> | ||||
| 					<p id='visibility'></p> | ||||
| 					<p><strong>members</strong></p> | ||||
| 					<h4>members</h4> | ||||
| 					<div id='memberlist'> | ||||
| 					</div> | ||||
| 				</div> | ||||
| 				<hr class='separator' color='#505050'> | ||||
| 			</div>`); | ||||
| 			</div> | ||||
| 			<hr class='separator' color='#505050'>`);
 | ||||
| 
 | ||||
| 	if (!instancediv.children['threads']) { | ||||
| 		instancediv.append(html.node` | ||||
|  |  | |||
|  | @ -249,6 +249,15 @@ async function get_user(msg, respond) { | |||
| 	}); | ||||
| } | ||||
| 
 | ||||
| async function list_users(msg, respond) { | ||||
| 	return respond({ | ||||
| 		success: true, | ||||
| 		users: (await db.query(` | ||||
| 			select id, name, coalesce(displayname, name) as displayname | ||||
| 			from user`)).rows
 | ||||
| 	}); | ||||
| } | ||||
| 
 | ||||
| async function get_keys(msg, respond) { | ||||
| 	// validate inputs
 | ||||
| 	if (!Array.isArray(msg.ids)) { | ||||
|  | @ -276,5 +285,6 @@ module.exports = { | |||
| 	authorize_key: authwrap(authorize_key), | ||||
| 	update_user: authwrap(update_user), | ||||
| 	get_user, | ||||
| 	list_users: authwrap(list_users), | ||||
| 	get_keys | ||||
| }; | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue