add better reaction popup
This commit is contained in:
parent
ae33a8a61b
commit
ecf7e3b4ce
14 changed files with 31442 additions and 14 deletions
|
|
@ -1057,8 +1057,10 @@ async function ensureUserKeys() {
|
|||
|
||||
async function mainJS() {
|
||||
await initBlahs();
|
||||
await loadEmotes();
|
||||
|
||||
passwordHash = await hashSHA3_512(password);
|
||||
|
||||
if (localStorage.getItem('lang') != null) {
|
||||
lang = localStorage.getItem('lang');
|
||||
}
|
||||
|
|
@ -2503,13 +2505,76 @@ async function replyMessage(msgId) {
|
|||
input.focus();
|
||||
}
|
||||
|
||||
var reactionPickerMenuHtml = "";
|
||||
var loadedEmotes = [];
|
||||
|
||||
async function loadEmotes() {
|
||||
try {
|
||||
let res = await fetch("emotes.json");
|
||||
let emotesObj = await res.json();
|
||||
let skinTones = ['\u{1F3FB}', '\u{1F3FC}', '\u{1F3FD}', '\u{1F3FE}', '\u{1F3FF}'];
|
||||
loadedEmotes = Object.keys(emotesObj).flatMap(char => {
|
||||
let baseEmote = { char: char, name: emotesObj[char].name, slug: emotesObj[char].slug };
|
||||
if (emotesObj[char].skin_tone_support) {
|
||||
let variants = skinTones.map(tone => ({
|
||||
char: char + tone,
|
||||
name: emotesObj[char].name + " skin tone",
|
||||
slug: emotesObj[char].slug
|
||||
}));
|
||||
return [baseEmote, ...variants];
|
||||
}
|
||||
return [baseEmote];
|
||||
});
|
||||
|
||||
reactionPickerMenuHtml = `
|
||||
<div style="display: flex; flex-direction: column; gap: 0.4rem; padding: 0.2rem; min-width: 14rem;">
|
||||
<input type="text" id="reaction-picker-search" placeholder="Type text / emoji..." oninput="filterReactions(this.value)" onkeydown="if(event.key === 'Enter') { if(this.value.trim() !== '') reactMessagePrompt(currentContextMenuMsgId, encodeURIComponent(this.value)); }" style="width: 100%; box-sizing: border-box; padding: 0.5rem 0.6rem; border-radius: 0.65rem; border: var(--border-width) solid var(--light-border-color); background: transparent; color: var(--text-color); font-family: inherit;">
|
||||
<div id="reaction-picker-grid" style="display: grid; grid-template-columns: repeat(5, 1fr); gap: 0.2rem; max-height: 12rem; overflow-y: auto; overflow-x: hidden;">
|
||||
${loadedEmotes.map(emoji => `<button onclick="reactMessagePrompt(currentContextMenuMsgId, encodeURIComponent('${emoji.char}'))" data-name="${emoji.name}" style="min-width: unset; width: 100%; aspect-ratio: 1; display: flex; justify-content: center; align-items: center; padding: 0; font-size: 1.2rem; border-radius: 0.65rem;" class="reaction-emoji-btn">${emoji.char}</button>`).join('')}
|
||||
</div>
|
||||
<button onclick="reactMessagePrompt(currentContextMenuMsgId, encodeURIComponent(document.getElementById('reaction-picker-search').value))" style="margin: 0; padding: 0.5rem; justify-content: center; border-radius: 0.65rem; width: 100%;">
|
||||
<span class="blah">title.text.react</span>
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
} catch (e) {
|
||||
console.error("Failed to load emotes", e);
|
||||
}
|
||||
}
|
||||
|
||||
function filterReactions(query) {
|
||||
let grid = document.getElementById("reaction-picker-grid");
|
||||
if (!grid) return;
|
||||
let buttons = grid.querySelectorAll(".reaction-emoji-btn");
|
||||
let lowerQuery = query.toLowerCase();
|
||||
buttons.forEach(btn => {
|
||||
let name = btn.getAttribute("data-name");
|
||||
if (name && name.toLowerCase().indexOf(lowerQuery) > -1) {
|
||||
btn.style.display = "flex";
|
||||
} else {
|
||||
btn.style.display = "none";
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function openReactionPicker(e) {
|
||||
if (e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
}
|
||||
if (!reactionPickerMenuHtml) return;
|
||||
let rect = fixedContextMenu.getBoundingClientRect();
|
||||
showFixedContextMenu({top: rect.top, right: rect.left, bottom: rect.top, left: rect.left}, reactionPickerMenuHtml);
|
||||
let searchInput = document.getElementById('reaction-picker-search');
|
||||
if (searchInput) searchInput.focus();
|
||||
}
|
||||
|
||||
async function reactMessagePrompt(msgId, quickReaction = null) {
|
||||
if (fixedContextMenu) fixedContextMenu.classList.remove("show");
|
||||
if (typeof clearContextMenuStyles === "function") clearContextMenuStyles();
|
||||
let reaction = quickReaction;
|
||||
if (!reaction) {
|
||||
reaction = prompt("Enter reaction (emoji or text):");
|
||||
if (!reaction) return;
|
||||
return;
|
||||
} else {
|
||||
reaction = decodeURIComponent(reaction);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue