mostly code organizing
							parent
							
								
									59d0b9eab2
								
							
						
					
					
						commit
						bf895466da
					
				
							
								
								
									
										130
									
								
								client/app.js
								
								
								
								
							
							
						
						
									
										130
									
								
								client/app.js
								
								
								
								
							|  | @ -1,66 +1,27 @@ | |||
| import { render, html } from '/uhtml.js'; | ||||
| import loadMessages from '/message.js'; | ||||
| import loadSpace from '/space.js'; | ||||
| 
 | ||||
| window.currentThreadId = 1; | ||||
| 
 | ||||
| function chooseThread(thread) { | ||||
| 	if (window.currentThreadId) { | ||||
| 		if (window.currentThreadId === thread.id) | ||||
| function chooseThread() { | ||||
| 	if (window.threadId) { | ||||
| 		if (window.threadId === this.thread.id) | ||||
| 			return; | ||||
| 		document.getElementById(`thread${window.currentThreadId}`) | ||||
| 		document.getElementById(`thread${window.threadId}`) | ||||
| 			.classList.remove('active'); | ||||
| 	} | ||||
| 	const el = document.getElementById(`thread${thread.id}`); | ||||
| 	el.classList.add('active'); | ||||
| 	window.currentThreadId = thread.id; | ||||
| 	window.earliestMessage = null; | ||||
| 	document.getElementById('threadname').textContent = thread.name; | ||||
| 	if (thread.permissions.post) | ||||
| 	document.getElementById('threadname').textContent = this.thread.name; | ||||
| 	this.classList.add('active'); | ||||
| 	window.threadId = this.thread.id; | ||||
| 	loadMessages(); | ||||
| 	if (this.thread.permissions.post) | ||||
| 		document.getElementById('msginput').classList.remove('hidden'); | ||||
| 	else | ||||
| 		document.getElementById('msginput').classList.add('hidden'); | ||||
| 	switchTab(document.getElementById(el.tab)); | ||||
| 	loadMessages(); | ||||
| 	if (el.tab === 'spacetab') | ||||
| 	switchTab(document.getElementById(this.tab)); | ||||
| 	if (this.tab === 'spacetab') | ||||
| 		loadSpace(); | ||||
| } | ||||
| 
 | ||||
| function loadMessages() { | ||||
| 	document.getElementById('messages').innerHTML = ''; | ||||
| 	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` | ||||
| 					<div class='message'> | ||||
| 						<strong>${message.name}: </strong> | ||||
| 						${message.message} | ||||
| 					</div>`); | ||||
| 			} | ||||
| 			if (!msg.more) | ||||
| 				document.getElementById('loadmore').classList.add('hidden'); | ||||
| 			else | ||||
| 				document.getElementById('loadmore').classList.remove('hidden'); | ||||
| 		} | ||||
| 	); | ||||
| } | ||||
| 
 | ||||
| function addThread(thread, top) { | ||||
| 	let node = html.node` | ||||
| 		<div class='thread' onclick=${() => chooseThread(thread)}>${ | ||||
| 		thread.name | ||||
| 	}</div>`; | ||||
| 	node.id = `thread${thread.id}`; | ||||
| 	node.tab = 'messagetab'; | ||||
| 	document.getElementById('threadlist')[top ? 'prepend' : 'appendChild'](node); | ||||
| } | ||||
| 
 | ||||
| function switchTab(tab) { | ||||
| 	for (let tab of document.querySelectorAll('.tab')) | ||||
| 		tab.classList.remove('active'); | ||||
|  | @ -139,35 +100,14 @@ async function createThread(e) { | |||
| 			members | ||||
| 		}, | ||||
| 		msg => { | ||||
| 			chooseThread({ | ||||
| 				name: name.value, | ||||
| 				id: msg.id, | ||||
| 				permissions: { | ||||
| 					is_member: true, | ||||
| 					view: true, | ||||
| 					post: true | ||||
| 				} | ||||
| 			}); | ||||
| 			chooseThread.call(document.getElementById('thread' + 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) { | ||||
|  | @ -214,7 +154,7 @@ function newThread() { | |||
| 
 | ||||
| function clickedTab(event) { | ||||
| 	switchTab(event.target); | ||||
| 	document.getElementById(`thread${window.currentThreadId}`).tab = event.target.id; | ||||
| 	document.getElementById(`thread${window.threadId}`).tab = event.target.id; | ||||
| } | ||||
| 
 | ||||
| render(document.body, html` | ||||
|  | @ -232,36 +172,30 @@ render(document.body, html` | |||
| 		<div id='tabs'> | ||||
| 			<button id='messagetab' class='tab active' onclick=${clickedTab}>messages</button><button id='spacetab' class='tab' onclick=${clickedTab}>space</button> | ||||
| 		</div> | ||||
| 		<div id='message' class='tabcontent'> | ||||
| 			<button id='loadmore' class='hidden' onclick=${loadMessages}> | ||||
| 			load more messages | ||||
| 			</button> | ||||
| 			<div id='messages'></div> | ||||
| 			<form id='msginput' onsubmit=${sendMessage}> | ||||
| 				<input type='text' placeholder='write a message...' id='msg' /> | ||||
| 				<button type='submit' id='sendmsg'>send</button> | ||||
| 			</form> | ||||
| 		</div> | ||||
| 		<div id='message' class='tabcontent'></div> | ||||
| 		<div id='space' class='tabcontent hidden'></div> | ||||
| 	</div> | ||||
| `);
 | ||||
| 
 | ||||
| window.socket.on('new_message', msg => { | ||||
| 	if (msg.thread !== window.currentThreadId) | ||||
| 		return; | ||||
| 	document.getElementById('messages').appendChild(html.node` | ||||
| 		<div class='message'> | ||||
| 			<strong>${msg.name}: </strong> | ||||
| 			${msg.message} | ||||
| 		</div>`); | ||||
| 	if (!window.earliestMessage) | ||||
| 		window.earliestMessage = msg.id; | ||||
| function makeThread(thread) { | ||||
| 	let node = html.node` | ||||
| 		<div class='thread' onclick=${chooseThread}>${ | ||||
| 			thread.name | ||||
| 		}</div>`; | ||||
| 	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.socket.on('new_thread', thread => addThread(thread, true)); | ||||
| 
 | ||||
| window.emit('list_threads', {}, msg => { | ||||
| 	document.getElementById('threadlist').innerHTML = ''; | ||||
| 	const threadlist = document.getElementById('threadlist') | ||||
| 	threadlist.innerHTML = ''; | ||||
| 	for (let thread of msg.threads) | ||||
| 		addThread(thread); | ||||
| 	chooseThread(msg.threads[0]); | ||||
| 		threadlist.appendChild(makeThread(thread)); | ||||
| 	chooseThread.call(threadlist.firstChild); | ||||
| }); | ||||
|  |  | |||
|  | @ -25,13 +25,6 @@ | |||
| 			::-webkit-scrollbar-corner { | ||||
| 				background-color: #111; | ||||
| 			} | ||||
| 			body, | ||||
| 			button, | ||||
| 			input { | ||||
| 				color: #eaeaea; | ||||
| 				border: none; | ||||
| 				outline: none; | ||||
| 			} | ||||
| 			html { | ||||
| 				height: 100%; | ||||
| 			} | ||||
|  | @ -43,28 +36,35 @@ | |||
| 				margin: 0; | ||||
| 				min-width: min-content; | ||||
| 			} | ||||
| 			#register { | ||||
| 				margin-inline: 14px; | ||||
| 			body, | ||||
| 			button, | ||||
| 			input { | ||||
| 				color: #eaeaea; | ||||
| 			} | ||||
| 			button { | ||||
| 				border: none; | ||||
| 				background: #303030; | ||||
| 			} | ||||
| 			button, | ||||
| 			input, | ||||
| 			.tab { | ||||
| 				padding: 5px 7px; | ||||
| 			} | ||||
| 			button { | ||||
| 				background: #303030; | ||||
| 			} | ||||
| 			input { | ||||
| 				background: #1b1b1b; | ||||
| 				padding-bottom: 3px; | ||||
| 				border-bottom: 2px solid transparent; | ||||
| 				outline: none; | ||||
| 				border: 1px solid #444; | ||||
| 			} | ||||
| 			input:focus { | ||||
| 				border-bottom: 2px solid #4f4f4f; | ||||
| 				padding-bottom: 3px; | ||||
| 				border-bottom: 3px solid #777; | ||||
| 			} | ||||
| 			input::placeholder { | ||||
| 				color: #aaa; | ||||
| 			} | ||||
| 			#register { | ||||
| 				margin-inline: 14px; | ||||
| 			} | ||||
| 			.thread:hover, | ||||
| 			.tab:hover { | ||||
| 				background-color: #3b3b3b; | ||||
|  | @ -147,7 +147,6 @@ | |||
| 			#msg { | ||||
| 				flex-grow: 1; | ||||
| 				margin: 2px; | ||||
| 				padding: 5px; | ||||
| 			} | ||||
| 			#sendmsg { | ||||
| 				margin: 2px 3px; | ||||
|  |  | |||
|  | @ -0,0 +1,75 @@ | |||
| import { render, html } from '/uhtml.js'; | ||||
| 
 | ||||
| let msg; | ||||
| 
 | ||||
| function sendMessage(e) { | ||||
| 	e.preventDefault(); | ||||
| 	if (!msg.value) | ||||
| 		return; | ||||
| 	window.emit('send_message', { | ||||
| 		message: msg.value, | ||||
| 		thread: window.threadId | ||||
| 	}); | ||||
| 	msg.value = ''; | ||||
| } | ||||
| 
 | ||||
| let earliestMessage; | ||||
| 
 | ||||
| window.socket.on('new_message', message => { | ||||
| 	if (message.thread !== window.threadId) | ||||
| 		return; | ||||
| 	document.getElementById('messages').appendChild(html.node` | ||||
| 		<div class='message'> | ||||
| 			<strong>${message.name}: </strong> | ||||
| 			${message.message} | ||||
| 		</div>`); | ||||
| 	if (!earliestMessage) | ||||
| 		earliestMessage = message.id; | ||||
| }); | ||||
| 
 | ||||
| function loadMessages() { | ||||
|    if (!msg) { | ||||
|       render(document.getElementById('message'), html` | ||||
|          <button id='loadmore' class='hidden' onclick=${loadMessages}> | ||||
|          load more messages | ||||
|          </button> | ||||
|          <div id='messages'></div> | ||||
|          <form id='msginput' onsubmit=${sendMessage}> | ||||
|             <input id='msg' placeholder='write a message...' /> | ||||
|             <button type='submit' id='sendmsg'>send</button> | ||||
|          </form> | ||||
|       `);
 | ||||
|       msg = document.getElementById('msg'); | ||||
|    } | ||||
|    const messages = document.getElementById('messages'); | ||||
|    if (!this) { // called from chooseThread, initializing thread
 | ||||
|    	messages.innerHTML = ''; | ||||
|       earliestMessage = null; | ||||
|    } | ||||
| 	window.emit( | ||||
| 		'get_history', | ||||
| 		{ | ||||
| 			before: earliestMessage, | ||||
| 			thread: window.threadId | ||||
| 		}, | ||||
| 		msg => { | ||||
|          if (!msg.success) | ||||
|             console.log('get_history failed: ' + msg.message); | ||||
| 			if (msg.messages.length > 0) { | ||||
| 				earliestMessage = msg.messages[msg.messages.length - 1].id; | ||||
| 				for (let message of msg.messages) | ||||
| 					messages.prepend(html.node` | ||||
|                   <div class='message'> | ||||
|                      <strong>${message.name}: </strong> | ||||
|                      ${message.message} | ||||
|                   </div>`); | ||||
| 			} | ||||
| 			if (!msg.more) | ||||
| 				document.getElementById('loadmore').classList.add('hidden'); | ||||
| 			else | ||||
| 				document.getElementById('loadmore').classList.remove('hidden'); | ||||
| 		} | ||||
| 	); | ||||
| } | ||||
| 
 | ||||
| export default loadMessages; | ||||
|  | @ -1,4 +1,5 @@ | |||
| let space; | ||||
| let spaceId; | ||||
| 
 | ||||
| let scale = 1; | ||||
| 
 | ||||
|  | @ -18,13 +19,15 @@ function mousemove(event) { | |||
| 
 | ||||
| function save(span) { | ||||
| 	window.emit('save_span', { | ||||
| 		thread: window.space, | ||||
| 		thread: spaceId, | ||||
| 		id: span.id ? span.id.slice(4) : '', | ||||
| 		content: span.innerText, | ||||
| 		x: span.style.left.slice(0, -2), | ||||
| 		y: span.style.top.slice(0, -2), | ||||
| 		scale: span.scale | ||||
| 	}, msg => { | ||||
| 		if (!msg.success) | ||||
| 			console.log('span save failed: ' + msg.message); | ||||
| 		if (!span.id) | ||||
| 			span.id = 'span' + msg.id; | ||||
| 	}); | ||||
|  | @ -59,7 +62,7 @@ function add(x, y, scale = 1) { | |||
| 		event.preventDefault(); | ||||
| 		this.scale *= 1 - event.deltaY * .001; | ||||
| 		this.style.transform = `translate(-50%, -50%) scale(${this.scale})`; | ||||
| 		//save
 | ||||
| 		save(this); | ||||
| 	}; | ||||
| 	span.onmousedown = function(event) { | ||||
| 		if (dragging || editing === this) | ||||
|  | @ -103,11 +106,13 @@ export default function loadSpace() { | |||
| 			editing.focus(); | ||||
| 		}; | ||||
| 	} | ||||
| 	if (window.space === window.currentThreadId) | ||||
| 	if (spaceId === window.threadId) | ||||
| 		return; | ||||
| 	window.space = window.currentThreadId; | ||||
| 	spaceId = window.threadId; | ||||
| 	space.innerHTML = ''; | ||||
| 	window.emit('get_space', { thread: window.space }, msg => { | ||||
| 	window.emit('get_space', { thread: window.threadId }, msg => { | ||||
| 		if (!msg.success) | ||||
| 			console.log('get space failed: ' + msg.message); | ||||
| 		for (const span of msg.spans) { | ||||
| 			let el = add(span.x, span.y, span.scale); | ||||
| 			el.innerText = span.content; | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue