All checks were successful
		
		
	
	Build Tilde Friends / Build-All (push) Successful in 18m1s
				
			
		
			
				
	
	
		
			175 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			175 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| import * as tfrpc from '/static/tfrpc.js';
 | |
| import {html, render} from './lit-all.min.js';
 | |
| import {styles, generate_theme} from './tf-styles.js';
 | |
| 
 | |
| let g_emojis;
 | |
| 
 | |
| function get_emojis() {
 | |
| 	if (g_emojis) {
 | |
| 		return Promise.resolve(g_emojis);
 | |
| 	}
 | |
| 	return fetch('emojis.json').then(function (result) {
 | |
| 		g_emojis = result.json();
 | |
| 		return g_emojis;
 | |
| 	});
 | |
| }
 | |
| 
 | |
| export async function picker(callback, anchor, author, recent) {
 | |
| 	let json = await get_emojis();
 | |
| 
 | |
| 	let div = document.createElement('div');
 | |
| 	div.id = 'emoji_picker';
 | |
| 	div.style.color = '#000';
 | |
| 	div.style.background = '#fff';
 | |
| 	div.style.border = '1px solid #000';
 | |
| 	div.style.display = 'flex';
 | |
| 	div.style.overflow = 'scroll';
 | |
| 	div.style.fontWeight = 'bold';
 | |
| 	div.style.fontSize = 'xx-large';
 | |
| 	div.style.flex = '1 1';
 | |
| 	div.style.flexDirection = 'column';
 | |
| 	let input = document.createElement('input');
 | |
| 	input.type = 'text';
 | |
| 	input.style.display = 'block';
 | |
| 	input.style.boxSizing = 'border-box';
 | |
| 	input.style.width = '100%';
 | |
| 	input.style.margin = '0';
 | |
| 	input.style.position = 'relative';
 | |
| 	div.appendChild(input);
 | |
| 	let list = document.createElement('div');
 | |
| 	list.style.overflow = 'scroll';
 | |
| 	div.appendChild(list);
 | |
| 	div.addEventListener('mousedown', function (event) {
 | |
| 		event.stopPropagation();
 | |
| 	});
 | |
| 
 | |
| 	function key_down(event) {
 | |
| 		if (event.key == 'Escape') {
 | |
| 			cleanup();
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	function chosen(event) {
 | |
| 		console.log(event.srcElement.innerText);
 | |
| 		callback(event.srcElement.innerText);
 | |
| 		cleanup();
 | |
| 	}
 | |
| 
 | |
| 	function refresh() {
 | |
| 		while (list.firstChild) {
 | |
| 			list.removeChild(list.firstChild);
 | |
| 		}
 | |
| 		let search = input.value.toLowerCase();
 | |
| 		let any_at_all = false;
 | |
| 		if (recent) {
 | |
| 			let emoji_to_name = {};
 | |
| 			for (let row of Object.values(json)) {
 | |
| 				for (let entry of Object.entries(row)) {
 | |
| 					emoji_to_name[entry[1]] = entry[0];
 | |
| 				}
 | |
| 			}
 | |
| 			let header = document.createElement('div');
 | |
| 			header.appendChild(document.createTextNode('Recent'));
 | |
| 			list.appendChild(header);
 | |
| 			let any = false;
 | |
| 			for (let entry of recent) {
 | |
| 				if (
 | |
| 					search &&
 | |
| 					search.length &&
 | |
| 					(emoji_to_name[entry] || '').toLowerCase().indexOf(search) == -1
 | |
| 				) {
 | |
| 					continue;
 | |
| 				}
 | |
| 				let emoji = document.createElement('span');
 | |
| 				const k_size = '1.25em';
 | |
| 				emoji.style.display = 'inline-block';
 | |
| 				emoji.style.overflow = 'hidden';
 | |
| 				emoji.style.cursor = 'pointer';
 | |
| 				emoji.onclick = chosen;
 | |
| 				emoji.title = emoji_to_name[entry] || entry;
 | |
| 				emoji.appendChild(document.createTextNode(entry));
 | |
| 				list.appendChild(emoji);
 | |
| 				any = true;
 | |
| 			}
 | |
| 			if (!any) {
 | |
| 				list.removeChild(header);
 | |
| 			}
 | |
| 		}
 | |
| 		for (let row of Object.entries(json)) {
 | |
| 			let header = document.createElement('div');
 | |
| 			header.appendChild(document.createTextNode(row[0]));
 | |
| 			list.appendChild(header);
 | |
| 			let any = false;
 | |
| 			for (let entry of Object.entries(row[1])) {
 | |
| 				if (
 | |
| 					search &&
 | |
| 					search.length &&
 | |
| 					entry[0].toLowerCase().indexOf(search) == -1
 | |
| 				) {
 | |
| 					continue;
 | |
| 				}
 | |
| 				let emoji = document.createElement('span');
 | |
| 				const k_size = '1.25em';
 | |
| 				emoji.style.display = 'inline-block';
 | |
| 				emoji.style.overflow = 'hidden';
 | |
| 				emoji.style.cursor = 'pointer';
 | |
| 				emoji.onclick = chosen;
 | |
| 				emoji.title = entry[0];
 | |
| 				emoji.appendChild(document.createTextNode(entry[1]));
 | |
| 				list.appendChild(emoji);
 | |
| 				any = true;
 | |
| 				any_at_all = true;
 | |
| 			}
 | |
| 			if (!any) {
 | |
| 				list.removeChild(header);
 | |
| 			}
 | |
| 		}
 | |
| 		if (!any_at_all) {
 | |
| 			list.appendChild(document.createTextNode('No matches found.'));
 | |
| 		}
 | |
| 	}
 | |
| 	refresh();
 | |
| 	input.oninput = refresh;
 | |
| 	let parent = document.createElement('div');
 | |
| 	function cleanup() {
 | |
| 		parent.parentElement.removeChild(parent);
 | |
| 		window.removeEventListener('keydown', key_down);
 | |
| 		document.body.removeEventListener('mousedown', cleanup);
 | |
| 	}
 | |
| 	let modal = html`
 | |
| 		<style>
 | |
| 			${styles}
 | |
| 		</style>
 | |
| 		<style>
 | |
| 			${generate_theme()}
 | |
| 		</style>
 | |
| 		<div
 | |
| 			class="w3-modal"
 | |
| 			style="display: block; box-sizing: border-box; z-index: 10"
 | |
| 		>
 | |
| 			<div class="w3-modal-content w3-card-4">
 | |
| 				<div
 | |
| 					class="w3-content w3-theme-d1"
 | |
| 					style="display: flex; flex-direction: column; max-height: 80vh"
 | |
| 				>
 | |
| 					<header class="w3-container" style="flex: 0 0">
 | |
| 						<h1>Choose a Reaction</h1>
 | |
| 						<span class="w3-button w3-display-topright" @click=${cleanup}
 | |
| 							>×</span
 | |
| 						>
 | |
| 					</header>
 | |
| 					${div}
 | |
| 					<footer class="w3-container w3-padding" style="flex: 0 0">
 | |
| 						<button class="w3-button" @click=${cleanup}>Close</button>
 | |
| 					</footer>
 | |
| 				</div>
 | |
| 			</div>
 | |
| 		</div>
 | |
| 	`;
 | |
| 	document.body.appendChild(parent);
 | |
| 	render(modal, parent);
 | |
| 	input.focus();
 | |
| 	document.body.addEventListener('mousedown', cleanup);
 | |
| 	window.addEventListener('keydown', key_down);
 | |
| }
 |