various updates
							parent
							
								
									03c0433c28
								
							
						
					
					
						commit
						af690ebea9
					
				
							
								
								
									
										107
									
								
								client/app.js
								
								
								
								
							
							
						
						
									
										107
									
								
								client/app.js
								
								
								
								
							|  | @ -18,8 +18,6 @@ function chooseThread() { | |||
| 	else | ||||
| 		document.getElementById('msginput').classList.add('hidden'); | ||||
| 	switchTab(document.getElementById(this.tab)); | ||||
| 	if (this.tab === 'spacetab') | ||||
| 		loadSpace(); | ||||
| } | ||||
| 
 | ||||
| function switchTab(tab) { | ||||
|  | @ -39,13 +37,13 @@ function addMember() { | |||
| 	const name = document.getElementById('membername').value; | ||||
| 	window.threadmembers.push(name); | ||||
| 	document | ||||
| 		.getElementById('memberlist') | ||||
| 		.getElementById('newmembers') | ||||
| 		.appendChild(html.node`<p class='member'>${name}</p>`); | ||||
| 	document.getElementById('membername').value = ''; | ||||
| } | ||||
| 
 | ||||
| async function createThread(e) { | ||||
| 	e.preventDefault(); | ||||
| async function createThread(event) { | ||||
| 	event.preventDefault(); | ||||
| 	let name = document.getElementById('newthreadname').value; | ||||
| 	if (!name) { | ||||
| 		document.getElementById('nameempty').classList.remove('hidden'); | ||||
|  | @ -112,42 +110,46 @@ 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` | ||||
| 			<form id='createthread' class='column' onsubmit=${createThread}> | ||||
| 				<h3>create thread</h3> | ||||
| 				<label for='newthreadname' class='heading'>thread name</label> | ||||
| 				<p id='nameempty' class='hidden'>name cannot be empty</p> | ||||
| 				<input type='text' id='newthreadname' /> | ||||
| 				<p id='permissions'>thread permissions</p> | ||||
| 				<input type='radio' id='public' name='permissions' value='public' checked /> | ||||
| 				<label for='public'>anyone can view and post</label><br /> | ||||
| 				<input type='radio' id='private_post' | ||||
| 					name='permissions' value='private_post' | ||||
| 				/> | ||||
| 				<label for='private_post'>anyone can view, only members can post</label><br/> | ||||
| 				<input type='radio' id='private_view' | ||||
| 					name='permissions' value='private_view' | ||||
| 				/> | ||||
| 				<label for='private_view'>only members can view and post</label | ||||
| 				><br /><br /> | ||||
| 				<label class='heading' for='membername'>members</label> | ||||
| 				<input type='text' id='membername' placeholder='username' onkeydown=${(e) => { | ||||
| 					if (e.key == 'Enter') { | ||||
| 						e.preventDefault(); | ||||
| 						addMember(); | ||||
| 					} | ||||
| 				}}/> | ||||
| 				<button id='addmember' onclick=${addMember}>add</button> | ||||
| 				<div id='memberlist'> | ||||
| 					<p class='member'>${window.name}</p> | ||||
| 				</div> | ||||
| 				<br /> | ||||
| 				<button id='submitthread' type='submit'>create</button> | ||||
| 			</form> | ||||
| 		`);
 | ||||
| 		document.getElementById('home') | ||||
| 			.insertAdjacentElement('afterend', html.node` | ||||
| 				<hr id='createseparator' class='separator' color='#666'>`)
 | ||||
| 			.insertAdjacentElement('afterend', html.node` | ||||
| 				<form id='createthread' class='column' onsubmit=${createThread}> | ||||
| 					<h3>create thread</h3> | ||||
| 					<label for='newthreadname' class='heading'>thread name</label> | ||||
| 					<p id='nameempty' class='hidden'>name cannot be empty</p> | ||||
| 					<input type='text' id='newthreadname' /> | ||||
| 					<p id='permissions'>thread permissions</p> | ||||
| 					<input type='radio' id='public' name='permissions' value='public' checked /> | ||||
| 					<label for='public'>anyone can view and post</label><br /> | ||||
| 					<input type='radio' id='private_post' | ||||
| 						name='permissions' value='private_post' | ||||
| 					/> | ||||
| 					<label for='private_post'>anyone can view, only members can post</label><br/> | ||||
| 					<input type='radio' id='private_view' | ||||
| 						name='permissions' value='private_view' | ||||
| 					/> | ||||
| 					<label for='private_view'>only members can view and post</label | ||||
| 					><br /><br /> | ||||
| 					<label class='heading' for='membername'>members</label> | ||||
| 					<input type='text' id='membername' placeholder='username' onkeydown=${event => { | ||||
| 						if (event.key === 'Enter') { | ||||
| 							event.preventDefault(); | ||||
| 							addMember(); | ||||
| 						} | ||||
| 					}}/> | ||||
| 					<button id='addmember' onclick=${addMember}>add</button> | ||||
| 					<div id='newmembers'> | ||||
| 						<p class='member'>${window.name}</p> | ||||
| 					</div> | ||||
| 					<br /> | ||||
| 					<button id='submitthread' type='submit'>create</button> | ||||
| 				</form> | ||||
| 			`);
 | ||||
| 		document.getElementById('newthread').textContent = 'cancel'; | ||||
| 	} | ||||
| } | ||||
|  | @ -157,6 +159,7 @@ function clickedTab(event) { | |||
| 	document.getElementById(`thread${window.threadId}`).tab = event.target.id; | ||||
| } | ||||
| 
 | ||||
| // main app html
 | ||||
| document.body.append(html.node` | ||||
| 	<div id='home' class='column'> | ||||
| 		<div id='threads'> | ||||
|  | @ -169,21 +172,35 @@ document.body.append(html.node` | |||
| 			document.getElementById('profile').classList.toggle('hidden') | ||||
| 		}>${window.name}</div> | ||||
| 	</div> | ||||
| 	<hr class='separator' color='#666'> | ||||
| 	<div id='profile' class='column hidden'> | ||||
| 		<p><strong>authentication requests</strong></p> | ||||
| 		<div id='authrequests'></div> | ||||
| 	</div> | ||||
| 	<hr class='separator' color='#666'> | ||||
| 	<div id='thread' class='column'> | ||||
| 		<div id='title'> | ||||
| 			thread: <strong id='threadname'>meow</strong> | ||||
| 		<div id='content'> | ||||
| 			<div id='title'> | ||||
| 				thread: <strong id='threadname'>meow</strong> | ||||
| 			</div> | ||||
| 			<div id='buttons'> | ||||
| 				<div id='tabs'> | ||||
| 					<button id='messagetab' class='tab active' onclick=${clickedTab}>messages | ||||
| 					</button><button id='spacetab' class='tab' onclick=${clickedTab}>space</button> | ||||
| 				</div> | ||||
| 				<button id='showmembers' onclick=${() => | ||||
| 					document.getElementById('members').classList.toggle('hidden') | ||||
| 				}>members</button> | ||||
| 			</div> | ||||
| 			<div id='message' class='tabcontent'></div> | ||||
| 			<div id='space' class='tabcontent hidden'></div> | ||||
| 		</div> | ||||
| 		<div id='tabs'> | ||||
| 			<button id='messagetab' class='tab active' onclick=${clickedTab}>messages | ||||
| 			</button><button id='spacetab' class='tab' onclick=${clickedTab}>space</button> | ||||
| 		<hr class='separator' color='#666'> | ||||
| 		<div id='members' class='hidden'> | ||||
| 			<p id='visibility'></p> | ||||
| 			<div id='memberlist'> | ||||
| 			</div> | ||||
| 		</div> | ||||
| 		<div id='message' class='tabcontent'></div> | ||||
| 		<div id='space' class='tabcontent hidden'></div> | ||||
| 	</div> | ||||
| `);
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -90,10 +90,15 @@ | |||
| 			} | ||||
| 			.column { | ||||
| 				flex: 1; | ||||
| 				margin: 2px; | ||||
| 			} | ||||
| 			.separator { | ||||
| 				margin: 8px 2px; | ||||
| 			} | ||||
| 			.separator:has(+ .separator), | ||||
| 			.separator:has(+ *.hidden) { | ||||
| 				display: none; | ||||
| 			} | ||||
| 			#home { | ||||
| 				max-width: 250px; | ||||
| 				display: flex; | ||||
|  | @ -101,17 +106,16 @@ | |||
| 				justify-content: space-between; | ||||
| 			} | ||||
| 			#threads { | ||||
| 				margin: 5px; | ||||
| 				margin: 3px; | ||||
| 			} | ||||
| 			#user { | ||||
| 				margin: 3px; | ||||
| 				padding: 6px; | ||||
| 				background-color: #191919; | ||||
| 			} | ||||
| 			#profile { | ||||
| 				max-width: 250px; | ||||
| 				> * { | ||||
| 					margin: 5px; | ||||
| 					margin: 4px; | ||||
| 				} | ||||
| 			} | ||||
| 			.authrequest { | ||||
|  | @ -119,25 +123,32 @@ | |||
| 			} | ||||
| 			.thread { | ||||
| 				padding: 2px 4px; | ||||
| 				white-space: pre; | ||||
| 			} | ||||
| 			#newthread { | ||||
| 				margin-top: 5px; | ||||
| 			} | ||||
| 			#createthread { | ||||
| 				max-width: 350px; | ||||
| 				max-width: fit-content; | ||||
| 			} | ||||
| 			#permissions { | ||||
| 				margin-bottom: 5px; | ||||
| 			} | ||||
| 			#thread { | ||||
| 				display: flex; | ||||
| 			} | ||||
| 			#content { | ||||
| 				flex: 1; | ||||
| 				display: flex; | ||||
| 				flex-direction: column; | ||||
| 			} | ||||
| 			#title { | ||||
| 				margin: 4px; | ||||
| 			} | ||||
| 			#tabs { | ||||
| 			#buttons { | ||||
| 				margin: 4px 2px; | ||||
| 				display: flex; | ||||
| 				justify-content: space-between; | ||||
| 			} | ||||
| 			.tab { | ||||
| 				padding: 5px 7px; | ||||
|  | @ -147,19 +158,22 @@ | |||
| 				font-weight: 500; | ||||
| 			} | ||||
| 			.tabcontent { | ||||
| 				flex-grow: 1; | ||||
| 				margin: 2px; | ||||
| 				flex: 1; | ||||
| 			} | ||||
| 			#message { | ||||
| 				margin: 2px; | ||||
| 				display: flex; | ||||
| 				flex-direction: column; | ||||
| 				min-height: 0; /* flex makes this auto so it can't shrink */ | ||||
| 			} | ||||
| 			#messages { | ||||
| 				margin: 2px; | ||||
| 				flex-grow: 1; | ||||
| 				flex: 1; | ||||
| 				overflow: auto; | ||||
| 			} | ||||
| 			#members { | ||||
| 				flex: 1; | ||||
| 				max-width: 250px; | ||||
| 			} | ||||
| 			#msginput { | ||||
| 				display: flex; | ||||
| 				flex-direction: row; | ||||
|  | @ -177,14 +191,11 @@ | |||
| 			#loadmore { | ||||
| 				margin-bottom: 10px; | ||||
| 			} | ||||
| 			.channel { | ||||
| 				font-weight: normal; | ||||
| 			} | ||||
| 			.member { | ||||
| 				margin: 5px 0; | ||||
| 			} | ||||
| 			#space { | ||||
| 				margin: 0; | ||||
| 				margin: -2px; /* offset column margin */ | ||||
| 				position: relative; | ||||
| 				overflow: auto; | ||||
| 			} | ||||
|  |  | |||
|  | @ -68,10 +68,11 @@ function loadMessages() { | |||
|                      ${message.message} | ||||
|                   </div>`); | ||||
| 			} | ||||
| 			if (!msg.more) | ||||
| 				document.getElementById('loadmore').classList.add('hidden'); | ||||
| 			else | ||||
| 			if (msg.more) | ||||
| 				document.getElementById('loadmore').classList.remove('hidden'); | ||||
| 			else | ||||
| 				document.getElementById('loadmore').classList.add('hidden'); | ||||
| 			messages.scroll(0, messages.scrollHeight - messages.clientHeight); | ||||
| 		} | ||||
| 	); | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue