various fixes
							parent
							
								
									c87c193118
								
							
						
					
					
						commit
						3b288c9719
					
				|  | @ -69,8 +69,11 @@ window.getUser = async (id, name) => { | |||
| 	); | ||||
| }; | ||||
| 
 | ||||
| window.makeUser = (user, url, removable) => { | ||||
| 	removable &&= window.currentThread.permissions.admin && !user.permissions?.admin; | ||||
| window.makeUser = (user, url, context) => { | ||||
| 	let removable = context === 'user' ? false : | ||||
| 		window.currentThread?.permissions.admin && !user.permissions?.admin && | ||||
| 		(context === 'member' ? true : Array.from(document.getElementById('memberlist').children) | ||||
| 			.find(p => p.children[0].user?.id == user.id)); | ||||
| 	let span = html.node` | ||||
| 		<span class='user' onclick=${function(e) { | ||||
| 			let member = document.getElementById('member'); | ||||
|  | @ -134,7 +137,7 @@ function instanceClicked(event) { | |||
| 		instance.emit?.('list_users', {}, msg => | ||||
| 			userlist.replaceChildren(...msg.users.map(user => { | ||||
| 				let p = document.createElement('p'); | ||||
| 				p.append(window.makeUser(user, instance.url)); | ||||
| 				p.append(window.makeUser(user, instance.url, 'user')); | ||||
| 				return p; | ||||
| 			})) | ||||
| 		); | ||||
|  | @ -192,32 +195,34 @@ document.body.append(html.node` | |||
| 			<input id='profilepublic' type='checkbox' oninput=${saveProfile}> | ||||
| 			<label for='profilepublic'>show profile in instance users</label> | ||||
| 		</p> | ||||
| 		<label class='heading'>authentication requests</label> | ||||
| 		<label class='heading'>authentication requests:</label> | ||||
| 		<div id='authrequests'></div> | ||||
| 	</div> | ||||
| 	<hr class='separator' color='#505050'> | ||||
| 	<div id='home' class='column'> | ||||
| 		<h3>vybe</h3> | ||||
| 		<p id='instances'>instances:<button onclick=${e => { | ||||
| 			let div = html.node` | ||||
| 				<div> | ||||
| 					<div class='instancetitle'> | ||||
| 						<span> </span> | ||||
| 						<span onblur=${addInstance} onkeydown=${function(event) { | ||||
| 							if (event.key === 'Enter') { | ||||
| 								event.preventDefault(); | ||||
| 								addInstance.call(this); | ||||
| 							} | ||||
| 						}} class='title' contenteditable='true'> | ||||
| 						</span> | ||||
| 					</div> | ||||
| 				</div>`; | ||||
| 			document.getElementById('instancelist').append(div); | ||||
| 			div.children[0].children[1].focus(); | ||||
| 		}}>add</button></p> | ||||
| 		<div id='instancelist'> | ||||
| 			<h3>vybe</h3> | ||||
| 			<p id='instances'>instances:<button onclick=${() => { | ||||
| 				let div = html.node` | ||||
| 					<div> | ||||
| 						<div class='instancetitle'> | ||||
| 							<span> </span> | ||||
| 							<span onblur=${addInstance} onkeydown=${function(event) { | ||||
| 								if (event.key === 'Enter') { | ||||
| 									event.preventDefault(); | ||||
| 									addInstance.call(this); | ||||
| 								} | ||||
| 							}} class='title' contenteditable='true'> | ||||
| 							</span> | ||||
| 						</div> | ||||
| 					</div>`; | ||||
| 				document.getElementById('instancelist').append(div); | ||||
| 				div.children[0].children[1].focus(); | ||||
| 			}}>add</button></p> | ||||
| 		</div> | ||||
| 		<div id='user' onclick=${() => | ||||
| 		<div class='content'><!-- empty flex div to push instancelist up --> | ||||
| 		</div> | ||||
| 		<div id='user' onclick=${e => | ||||
| 			document.getElementById('profile').classList.toggle('hidden') | ||||
| 		}>${window.name}</div> | ||||
| 	</div> | ||||
|  |  | |||
|  | @ -174,7 +174,8 @@ | |||
| 			.user { | ||||
| 				white-space: pre-wrap; | ||||
| 				&:hover { | ||||
| 					background-color: #444; | ||||
| 					background-color: #333; | ||||
| 					border-bottom: 1px #bbb solid; | ||||
| 				} | ||||
| 			} | ||||
| 			#profile { | ||||
|  |  | |||
|  | @ -72,8 +72,7 @@ function loadMessages(callback) { | |||
| 					} | ||||
| 				} | ||||
| 				let div = html.node`<div class='message'>: ${message.content}</div>`; | ||||
| 				div.prepend(user ? window.makeUser(user, | ||||
| 						user.id.split?.('@')[1] || instance.url, true) | ||||
| 				div.prepend(user ? window.makeUser(user, user.id.split?.('@')[1] || instance.url) | ||||
| 					: html.node`<span>${message.user.id}</span>`); | ||||
| 				messages.prepend(div); | ||||
| 			} | ||||
|  | @ -93,7 +92,7 @@ function loadMessages(callback) { | |||
| 			let scroll = messages.scrollTop + 10 >= messages.scrollHeight - messages.clientHeight; | ||||
| 			let div = html.node`<div class='message'>: ${message.content}</div>`; | ||||
| 			div.prepend(window.makeUser(message.user, | ||||
| 				message.user.id.split?.('@')[1] || instance.url, true)); | ||||
| 				message.user.id.split?.('@')[1] || instance.url)); | ||||
| 			messages.append(div); | ||||
| 			if (scroll) | ||||
| 				messages.scroll(0, messages.scrollHeight - messages.clientHeight); | ||||
|  |  | |||
|  | @ -78,7 +78,7 @@ function loadStreams() { | |||
| 
 | ||||
| 	let div = document.getElementById('stream'); | ||||
| 	div.innerHTML = ''; | ||||
| 	if (window.currentThread.permissions.post) { | ||||
| 	if (window.currentThread?.permissions.post) { | ||||
| 		// why doesn't html` work here? html.node` does
 | ||||
| 		render(div, html.node` | ||||
| 			<button id='streaming' onclick=${stream}> | ||||
|  | @ -92,7 +92,10 @@ function loadStreams() { | |||
| 						thread: window.currentThread.id, | ||||
| 						name: this.value | ||||
| 					}); | ||||
| 				window.currentThread.streamname = this.value; | ||||
| 			}}>`);
 | ||||
| 		if (window.currentThread.streamname) | ||||
| 			document.getElementById('streamname').value = window.currentThread.streamname; | ||||
| 	} | ||||
| 	div.insertAdjacentHTML('beforeend', ` | ||||
| 		<p>streams:</p> | ||||
|  | @ -123,8 +126,11 @@ function loadStreams() { | |||
| 							console.log('play stream failed: ', msg.message); | ||||
| 					}); | ||||
| 				}}>${instance.streaming[stream.id] ? '⏹' : '▶'}</button> | ||||
| 				${stream.user}<span id='name'>${stream.name ? ` - ${stream.name}` : ''}</span> | ||||
| 				<span id='name'>${stream.name ? ` - ${stream.name}` : ''}</span> | ||||
| 			</p>`; | ||||
| 		p.insertBefore(window.makeUser(stream.user, | ||||
| 			stream.user.id.split?.('@')[1] || window.currentInstance.url), | ||||
| 			p.children[1]); | ||||
| 		p.id = 'stream' + stream.id; | ||||
| 		document.getElementById('streams').append(p); | ||||
| 	} | ||||
|  | @ -167,8 +173,9 @@ function loadStreams() { | |||
| 		}); | ||||
| 	} | ||||
| 
 | ||||
| 	for (let stream of window.currentThread.streams) | ||||
| 		addStream(stream); | ||||
| 	if (window.currentThread) | ||||
| 		for (let stream of window.currentThread.streams) | ||||
| 			addStream(stream); | ||||
| } | ||||
| 
 | ||||
| export default loadStreams; | ||||
|  |  | |||
|  | @ -39,26 +39,17 @@ function chooseThread() { | |||
| 	} | ||||
| 	else | ||||
| 		document.getElementById('thread').classList.remove('hidden'); | ||||
| 	if (thread.permissions.admin) | ||||
| 	if (thread.permissions.admin) { | ||||
| 		edit.classList.remove('hidden'); | ||||
| 	else | ||||
| 		document.getElementById('membersadd').classList.remove('hidden'); | ||||
| 	} else { | ||||
| 		edit.classList.add('hidden'); | ||||
| 		document.getElementById('membersadd').classList.add('hidden'); | ||||
| 	} | ||||
| 	document.getElementById('threadname').textContent = thread.name; | ||||
| 	this.classList.add('active'); | ||||
| 	window.currentThread = thread; | ||||
| 	window.currentInstance = thread.instance; | ||||
| 	let tab = url.searchParams.get('tab'); | ||||
| 	if (!['message', 'space', 'stream'].includes(tab)) | ||||
| 		tab = null; | ||||
| 	if (tab || this.tab) { | ||||
| 		if (tab) | ||||
| 			this.tab = tab + 'tab'; | ||||
| 		switchTab(document.getElementById(this.tab)); | ||||
| 		if (this.tab === 'messagetab') | ||||
| 			loadMessages(); | ||||
| 		else if (this.tab === 'spacetab') | ||||
| 			loadSpace(); | ||||
| 	} | ||||
| 	let div = this; | ||||
| 	window.currentInstance.emit('get_thread', { thread: thread.id }, async msg => { | ||||
| 		if (!msg.success) { | ||||
|  | @ -71,13 +62,13 @@ function chooseThread() { | |||
| 			...await Promise.all(msg.thread.members.map(async member => { | ||||
| 				let p = document.createElement('p'); | ||||
| 				if (member.name) | ||||
| 					p.append(window.makeUser(member, window.currentInstance.url, true)); | ||||
| 					p.append(window.makeUser(member, window.currentInstance.url, 'member')); | ||||
| 				else | ||||
| 					try { | ||||
| 						let user = await window.getUser(member.id); | ||||
| 						user.id = member.id; | ||||
| 						user.permissions = member.permissions; | ||||
| 						p.append(window.makeUser(user, user.id.split?.('@')[1], true)); | ||||
| 						p.append(window.makeUser(user, user.id.split?.('@')[1], 'member')); | ||||
| 					} | ||||
| 					catch (e) { | ||||
| 						console.log(`error getting user ${member.id}: ${e}`); | ||||
|  | @ -87,9 +78,20 @@ function chooseThread() { | |||
| 			})) | ||||
| 		); | ||||
| 		loadStreams(); | ||||
| 		if (!div.tab) | ||||
| 		let tab = url.searchParams.get('tab'); | ||||
| 		if (!['message', 'space', 'stream'].includes(tab)) | ||||
| 			tab = null; | ||||
| 		if (tab || this.tab) { | ||||
| 			if (tab) | ||||
| 				this.tab = tab + 'tab'; | ||||
| 			switchTab(document.getElementById(this.tab)); | ||||
| 			if (this.tab === 'messagetab') | ||||
| 				loadMessages(); | ||||
| 			else if (this.tab === 'spacetab') | ||||
| 				loadSpace(); | ||||
| 		} | ||||
| 		else // load first tab that has any content
 | ||||
| 			await new Promise(resolve => { | ||||
| 				// load first tab that has any content
 | ||||
| 				loadMessages(messages => { | ||||
| 					if (messages.length) { | ||||
| 						switchTab(document.getElementById(div.tab = 'messagetab')); | ||||
|  | @ -108,8 +110,13 @@ function chooseThread() { | |||
| 						}); | ||||
| 				}); | ||||
| 			}); | ||||
| 		url.searchParams.set('thread', thread.id); | ||||
| 		url.searchParams.set('tab', div.tab.substring(0, div.tab.length - 3)); | ||||
| 		if (window.currentInstance === window.instancelist[0]) { | ||||
| 			url.searchParams.set('thread', thread.id); | ||||
| 			url.searchParams.set('tab', div.tab.substring(0, div.tab.length - 3)); | ||||
| 		} else { | ||||
| 			url.searchParams.delete('thread'); | ||||
| 			url.searchParams.delete('tab'); | ||||
| 		} | ||||
| 		window.history.pushState(null, '', url.toString()); | ||||
| 	}); | ||||
| } | ||||
|  | @ -327,10 +334,8 @@ async function addMember() { | |||
| 		name.value = ''; | ||||
| 		document.getElementById('addmember').classList.add('hidden'); | ||||
| 	} | ||||
| 	if (!name.value) { | ||||
| 		close(); | ||||
| 		return; | ||||
| 	} | ||||
| 	if (!name.value) | ||||
| 		return close(); | ||||
| 	let at = name.value.split('@'); | ||||
| 	let url = at[1] || window.currentInstance.url; | ||||
| 	let user = await window.getUser('@' + url, at[0]); | ||||
|  | @ -339,15 +344,11 @@ async function addMember() { | |||
| 		return; | ||||
| 	} | ||||
| 	error.innerText = ''; | ||||
| 	if (window.currentInstance.url !== url) { | ||||
| 	if (window.currentInstance.url !== url) | ||||
| 		user.id += '@' + url; | ||||
| 		user.name += '@' + url; | ||||
| 	} | ||||
| 	for (let p of document.getElementById('memberlist').children) | ||||
| 		if (p.children[0].user.id == user.id) { | ||||
| 			close(); | ||||
| 			return; | ||||
| 		} | ||||
| 		if (p.children[0].user.id == user.id) | ||||
| 			return close(); | ||||
| 	window.currentInstance.emit('add_member', { | ||||
| 		id: String(user.id), | ||||
| 		thread: window.currentThread.id | ||||
|  | @ -359,7 +360,7 @@ async function addMember() { | |||
| 		} | ||||
| 		close(); | ||||
| 		let p = document.createElement('p'); | ||||
| 		p.append(window.makeUser(user, url, true)); | ||||
| 		p.append(window.makeUser(user, url, 'member')); | ||||
| 		document.getElementById('memberlist').append(p); | ||||
| 	}); | ||||
| } | ||||
|  | @ -404,7 +405,7 @@ async function loadThreads(instancediv, select) { | |||
| 				<p id='visibility'></p> | ||||
| 				<div id='membershead'> | ||||
| 					<strong>members</strong> | ||||
| 					<button onclick=${e => { | ||||
| 					<button id='membersadd' onclick=${e => { | ||||
| 						document.getElementById('addmember').classList.remove('hidden'); | ||||
| 						document.getElementById('addmembername').focus(); | ||||
| 					}}>add</button> | ||||
|  |  | |||
|  | @ -26,8 +26,7 @@ async function stream(msg, respond, socket) { | |||
| 					socket.emit('stream', stream); | ||||
| 		} else { | ||||
| 			for (let member of ( | ||||
| 				await db.query( | ||||
| 					'select user from member where member.thread = ?', msg.thread) | ||||
| 				await db.query('select user from member where member.thread = ?', msg.thread) | ||||
| 			).rows) { | ||||
| 				member = vybe.users[member.user]; | ||||
| 				if (member) | ||||
|  | @ -49,19 +48,30 @@ async function stream(msg, respond, socket) { | |||
| 				message: "stream doesn't belong to user" | ||||
| 			}); | ||||
| 		if (msg.stop) { | ||||
| 			stream.stop(); | ||||
| 			await stream.stop(); | ||||
| 			return respond({ | ||||
| 				success: true | ||||
| 			}); | ||||
| 		} | ||||
| 		stream = stream.stream; | ||||
| 		stream.name = msg.name; | ||||
| 		stream.user.displayname = msg.auth_user.displayname; | ||||
| 	} | ||||
| 	else { | ||||
| 		stream = { | ||||
| 			id: newstreamid++, | ||||
| 			thread: msg.thread, | ||||
| 			user: msg.auth_user.displayname, | ||||
| 			user: { | ||||
| 				id: msg.auth_user.id, | ||||
| 				name: msg.auth_user.name, | ||||
| 				displayname: msg.auth_user.displayname, | ||||
| 				permissions: Object.fromEntries((await db.query( | ||||
| 					`select permission, value from permission
 | ||||
| 					where type = 'user' and thread = ? and user = ?`,
 | ||||
| 					[msg.thread, msg.auth_user.id])).rows.map(p => | ||||
| 						[p.permission, ['admin', 'post', 'view'].includes(p.permission) | ||||
| 							? p.value === 'true' : p.value])) | ||||
| 			}, | ||||
| 			name: msg.name | ||||
| 		}; | ||||
| 		thread.streams.push(stream); | ||||
|  | @ -70,11 +80,11 @@ async function stream(msg, respond, socket) { | |||
| 			userid: msg.auth_user.id, | ||||
| 			listeners: {}, | ||||
| 			socket: socket.id, | ||||
| 			stop: () => { | ||||
| 			stop: async () => { | ||||
| 				stream.stopped = true; | ||||
| 				thread.streams.splice(thread.streams.findIndex(s => s.id === stream.id), 1); | ||||
| 				delete vybe.streams[stream.id]; | ||||
| 				send(); | ||||
| 				await send(); | ||||
| 			} | ||||
| 		}; | ||||
| 	} | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue