forked from andyburke/autonomous.contact
		
	
		
			
	
	
		
			176 lines
		
	
	
	
		
			4.8 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
		
		
			
		
	
	
			176 lines
		
	
	
	
		
			4.8 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
|  | <div id="talk" class="tab"> | ||
|  | 	<input | ||
|  | 		type="radio" | ||
|  | 		name="top-level-tabs" | ||
|  | 		id="talk-tab-input" | ||
|  | 		class="tab-switch" | ||
|  | 		data-hash="/talk" | ||
|  | 	/> | ||
|  | 	<label for="talk-tab-input" class="tab-label" | ||
|  | 		><div class="icon talk"></div> | ||
|  | 		<div class="label">Talk</div> | ||
|  | 	</label> | ||
|  | 	<div class="tab-content"> | ||
|  | 		<style> | ||
|  | 			<!-- #include file="./talk.css" --> | ||
|  | 		</style> | ||
|  | 		<script src="./js/external/punycode.js" type="text/javascript"></script> | ||
|  | 		<script> | ||
|  | 			<!-- #include file="./talk.js" --> | ||
|  | 		</script> | ||
|  | 		<div class="sidebar resizable"> | ||
|  | 			<div id="room-creation-container" data-requires-permission="rooms.create"> | ||
|  | 				<button | ||
|  | 					id="toggle-room-creation-form-button" | ||
|  | 					onclick="((event) => { | ||
|  | 						event.preventDefault(); | ||
|  | 					 	const room_create_form = document.getElementById( 'room-create' ); | ||
|  | 						room_create_form.style[ 'height' ] = room_create_form.style[ 'height' ] === '5rem' ? '0' : '5rem'; | ||
|  | 					})(event)" | ||
|  | 				> | ||
|  | 					<div class="icon plus"></div> | ||
|  | 				</button> | ||
|  | 				<form | ||
|  | 					id="room-create" | ||
|  | 					data-smart="true" | ||
|  | 					action="/api/rooms" | ||
|  | 					method="POST" | ||
|  | 					style=" | ||
|  | 						margin-top: 1rem; | ||
|  | 						width: 100%; | ||
|  | 						overflow: hidden; | ||
|  | 						height: 0; | ||
|  | 						overflow: hidden; | ||
|  | 						transition: all 0.5s; | ||
|  | 					" | ||
|  | 				> | ||
|  | 					<input | ||
|  | 						id="new-room-name-input" | ||
|  | 						type="text" | ||
|  | 						name="name" | ||
|  | 						value="" | ||
|  | 						placeholder="new room" | ||
|  | 					/> | ||
|  | 					<!-- <button class="primary" type="submit">
 | ||
|  | 						<div class="icon plus"></div> | ||
|  | 					</button> --> | ||
|  | 					<input type="submit" hidden /> | ||
|  | 					<script> | ||
|  | 						{ | ||
|  | 							const form = document.currentScript.closest("form"); | ||
|  | 							const room_create_form = document.getElementById("room-create"); | ||
|  | 							const new_room_name_input = | ||
|  | 								document.getElementById("new-room-name-input"); | ||
|  | 
 | ||
|  | 							form.on_reply = (new_room) => { | ||
|  | 								const room_list = document.getElementById("room-list"); | ||
|  | 								room_list.insertAdjacentHTML( | ||
|  | 									"beforeend", | ||
|  | 									`<li id="room-selector-${new_room.id}" class="room"><a href="#/room/${new_room.id}">${new_room.name}</a></li>`, | ||
|  | 								); | ||
|  | 
 | ||
|  | 								new_room_name_input.value = ""; | ||
|  | 								window.location.hash = `/talk/room/${new_room.id}`; | ||
|  | 								room_create_form.style["height"] = "0"; | ||
|  | 							}; | ||
|  | 						} | ||
|  | 					</script> | ||
|  | 				</form> | ||
|  | 			</div> | ||
|  | 			<div> | ||
|  | 				<span class="title">chat rooms</span> | ||
|  | 			</div> | ||
|  | 			<ul id="room-list" class="room-list"></ul> | ||
|  | 		</div> | ||
|  | 		<div id="room-chat-container"> | ||
|  | 			<div id="room-chat-content"></div> | ||
|  | 			<div id="room-chat-entry-container"> | ||
|  | 				<form id="room-chat-entry" action="" data-smart="true" data-method="POST"> | ||
|  | 					<button aria-label="Attach file"> | ||
|  | 						<i class="icon attachment"></i> | ||
|  | 					</button> | ||
|  | 					<textarea | ||
|  | 						id="room-chat-input" | ||
|  | 						class="room-chat-input" | ||
|  | 						rows="1" | ||
|  | 						name="data.message" | ||
|  | 					></textarea> | ||
|  | 					<button id="room-chat-send" class="primary" aria-label="Send a message"> | ||
|  | 						<i class="icon send"></i> | ||
|  | 					</button> | ||
|  | 
 | ||
|  | 					<script> | ||
|  | 						{ | ||
|  | 							const form = document.currentScript.closest("form"); | ||
|  | 							const chat_input = document.getElementById("room-chat-input"); | ||
|  | 							const room_chat_container = | ||
|  | 								document.getElementById("room-chat-container"); | ||
|  | 							const room_chat_content = document.getElementById("room-chat-content"); | ||
|  | 
 | ||
|  | 							let messages_in_flight = {}; | ||
|  | 
 | ||
|  | 							chat_input.addEventListener("keypress", (event) => { | ||
|  | 								if (event.key === "Enter" && !event.shiftKey) { | ||
|  | 									form.requestSubmit(); | ||
|  | 								} | ||
|  | 							}); | ||
|  | 
 | ||
|  | 							form.on_submit = (event) => { | ||
|  | 								const message = chat_input.value.trim(); | ||
|  | 								if (message.length === 0) { | ||
|  | 									return false; | ||
|  | 								} | ||
|  | 
 | ||
|  | 								const room_id = room_chat_container.dataset.room_id; | ||
|  | 								if (!room_id) { | ||
|  | 									alert("Failed to get room_id!"); | ||
|  | 									return false; | ||
|  | 								} | ||
|  | 
 | ||
|  | 								form.action = `/api/rooms/${room_id}/events`; | ||
|  | 							}; | ||
|  | 
 | ||
|  | 							form.on_parsed = (json) => { | ||
|  | 								const now = new Date().toISOString(); | ||
|  | 
 | ||
|  | 								const temp_id = `TEMP-${now}`; | ||
|  | 								json.id = temp_id; | ||
|  | 								json.type = "chat"; | ||
|  | 								json.meta = { | ||
|  | 									temp_id, | ||
|  | 								}; | ||
|  | 								json.timestamps = { | ||
|  | 									created: now, | ||
|  | 									updated: now, | ||
|  | 								}; | ||
|  | 
 | ||
|  | 								const user = JSON.parse(document.body.dataset.user); | ||
|  | 								render_text_event(room_chat_content, json, user); | ||
|  | 								document | ||
|  | 									.getElementById(`chat-${temp_id}`) | ||
|  | 									?.classList.add("sending"); | ||
|  | 							}; | ||
|  | 
 | ||
|  | 							form.on_error = (error) => { | ||
|  | 								// TODO: mark the temporary message element with the failed class? | ||
|  | 								alert(error); | ||
|  | 								chat_input.focus(); | ||
|  | 							}; | ||
|  | 
 | ||
|  | 							form.on_reply = (sent_message) => { | ||
|  | 								document | ||
|  | 									.getElementById(`chat-${sent_message.meta?.temp_id ?? ""}`) | ||
|  | 									?.classList.remove("sending"); | ||
|  | 
 | ||
|  | 								append_room_events([sent_message]); | ||
|  | 								chat_input.value = ""; | ||
|  | 								chat_input.focus(); | ||
|  | 							}; | ||
|  | 						} | ||
|  | 					</script> | ||
|  | 				</form> | ||
|  | 			</div> | ||
|  | 		</div> | ||
|  | 	</div> | ||
|  | </div> |