import * as tfrpc from '/static/tfrpc.js'; import {html, render} from './lit-all.min.js'; import {styles} 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; }); } async function get_recent(author) { let recent = await tfrpc.rpc.query( ` SELECT DISTINCT content ->> '$.vote.expression' AS value FROM messages WHERE author = ? AND content ->> '$.type' = 'vote' ORDER BY timestamp DESC LIMIT 10 `, [author] ); return recent.map((x) => x.value); } export async function picker(callback, anchor, author) { let json = await get_emojis(); let recent = await get_recent(author); 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 = 'block'; div.style.overflow = 'scroll'; div.style.fontWeight = 'bold'; div.style.fontSize = 'xx-large'; 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'); 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 modal = html`
${div}
`; let parent = document.createElement('div'); document.body.appendChild(parent); function cleanup() { parent.parentElement.removeChild(parent); window.removeEventListener('keydown', key_down); document.body.removeEventListener('mousedown', cleanup); } render(modal, parent); input.focus(); document.body.addEventListener('mousedown', cleanup); window.addEventListener('keydown', key_down); }