Show recently used emojis in the emoji picker. #16

This commit is contained in:
Cory McWilliams 2024-04-04 02:12:43 +01:00
parent 9671413906
commit 68e8c010b7
3 changed files with 141 additions and 93 deletions

View File

@ -1,5 +1,5 @@
{ {
"type": "tildefriends-app", "type": "tildefriends-app",
"emoji": "🐌", "emoji": "🐌",
"previous": "&uSuRSjzMShdQllrt3gVYhWlixI6o6n0c1c/+pEhJCCI=.sha256" "previous": "&W6OyIT7eLYsiAZ6BHEAsvF+OJXlVgFs1MH1eLf+EhkQ=.sha256"
} }

View File

@ -1,3 +1,5 @@
import * as tfrpc from '/static/tfrpc.js';
let g_emojis; let g_emojis;
function get_emojis() { function get_emojis() {
@ -10,105 +12,151 @@ function get_emojis() {
}); });
} }
export function picker(callback, anchor) { async function get_recent(author) {
get_emojis().then(function (json) { let recent = await tfrpc.rpc.query(`
let div = document.createElement('div'); SELECT DISTINCT content ->> '$.vote.expression' AS value
div.id = 'emoji_picker'; FROM messages
div.style.color = '#000'; WHERE author = ? AND
div.style.background = '#fff'; content ->> '$.type' = 'vote'
div.style.border = '1px solid #000'; ORDER BY timestamp DESC LIMIT 10
div.style.display = 'block'; `, [author]);
div.style.position = 'absolute'; return recent.map(x => x.value);
div.style.minWidth = 'min(16em, 90vw)'; }
div.style.width = 'min(16em, 90vw)';
div.style.maxWidth = 'min(16em, 90vw)';
div.style.maxHeight = '16em';
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 cleanup() { export async function picker(callback, anchor, author) {
console.log('emoji cleanup'); let json = await get_emojis();
div.parentElement.removeChild(div); let recent = await get_recent(author);
window.removeEventListener('keydown', key_down);
console.log('removing click');
document.body.removeEventListener('mousedown', cleanup);
}
function key_down(event) { let div = document.createElement('div');
if (event.key == 'Escape') { div.id = 'emoji_picker';
cleanup(); div.style.color = '#000';
} div.style.background = '#fff';
} div.style.border = '1px solid #000';
div.style.display = 'block';
div.style.position = 'absolute';
div.style.minWidth = 'min(16em, 90vw)';
div.style.width = 'min(16em, 90vw)';
div.style.maxWidth = 'min(16em, 90vw)';
div.style.maxHeight = '16em';
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 chosen(event) { function cleanup() {
console.log(event.srcElement.innerText); console.log('emoji cleanup');
callback(event.srcElement.innerText); div.parentElement.removeChild(div);
window.removeEventListener('keydown', key_down);
console.log('removing click');
document.body.removeEventListener('mousedown', cleanup);
}
function key_down(event) {
if (event.key == 'Escape') {
cleanup(); cleanup();
} }
}
function refresh() { function chosen(event) {
while (list.firstChild) { console.log(event.srcElement.innerText);
list.removeChild(list.firstChild); callback(event.srcElement.innerText);
} cleanup();
let search = input.value.toLowerCase(); }
let any_at_all = false;
for (let row of Object.entries(json)) { function refresh() {
let header = document.createElement('div'); while (list.firstChild) {
header.appendChild(document.createTextNode(row[0])); list.removeChild(list.firstChild);
list.appendChild(header); }
let any = false; let search = input.value.toLowerCase();
for (let entry of Object.entries(row[1])) { let any_at_all = false;
if ( if (recent) {
search && let emoji_to_name = {};
search.length && for (let row of Object.values(json)) {
entry[0].toLowerCase().indexOf(search) == -1 for (let entry of Object.entries(row)) {
) { emoji_to_name[entry[1]] = entry[0];
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) { let header = document.createElement('div');
list.appendChild(document.createTextNode('No matches found.')); 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);
} }
} }
refresh(); for (let row of Object.entries(json)) {
input.oninput = refresh; let header = document.createElement('div');
document.body.appendChild(div); header.appendChild(document.createTextNode(row[0]));
div.style.position = 'fixed'; list.appendChild(header);
div.style.top = '50%'; let any = false;
div.style.left = '50%'; for (let entry of Object.entries(row[1])) {
div.style.transform = 'translate(-50%, -50%)'; if (
input.focus(); search &&
console.log('adding click'); search.length &&
document.body.addEventListener('mousedown', cleanup); entry[0].toLowerCase().indexOf(search) == -1
window.addEventListener('keydown', key_down); ) {
}); 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;
document.body.appendChild(div);
div.style.position = 'fixed';
div.style.top = '50%';
div.style.left = '50%';
div.style.transform = 'translate(-50%, -50%)';
input.focus();
console.log('adding click');
document.body.addEventListener('mousedown', cleanup);
window.addEventListener('keydown', key_down);
} }

View File

@ -125,7 +125,7 @@ class TfMessageElement extends LitElement {
} }
react(event) { react(event) {
emojis.picker((x) => this.vote(x)); emojis.picker((x) => this.vote(x), null, this.whoami);
} }
show_image(link) { show_image(link) {