Update static/js/10-reactions.js

This commit is contained in:
dev 2026-10-31 08:46:36 +00:00
parent b85df7fdbd
commit ead6a4f709

View File

@ -5,8 +5,13 @@ window.Glow = window.Glow || {};
Glow.reactions = Glow.reactions || { Glow.reactions = Glow.reactions || {
enabled: true, enabled: true,
emojis: ["👍", "❤️", "🔥", "😂", "🎉", "👏", "😮", "😢", "👀", "✅", "🚀", "💡"], emojis: [
activeMessage: null "👍", "👎", "❤️", "🔥", "😂", "😄", "🙂", "😭",
"👏", "🙌", "🎉", "✨", "💯", "✅", "👀", "🤔",
"🙏", "💡", "⭐", "🚀", "😮", "😢", "😡", "👋"
],
activeMessage: null,
selectedIndex: 0
}; };
Glow.submitCustomReaction = async () => { Glow.submitCustomReaction = async () => {
@ -41,8 +46,47 @@ Glow.submitCustomReaction = async () => {
} }
}; };
Glow.highlightReactionSelection = () => {
const grid = Glow.els.reactionPopupGrid;
if (!grid) return;
const buttons = [...grid.querySelectorAll(".reaction-popup-button")];
buttons.forEach((button, index) => {
button.classList.toggle("active", index === Glow.reactions.selectedIndex);
});
};
Glow.activateReactionAtIndex = async index => {
const message = Glow.reactions.activeMessage;
const emoji = Glow.reactions.emojis[index];
if (!message || !emoji) return;
try {
const existing = (message.reactions || []).find(item => item.emoji === emoji);
if (existing?.reacted) {
await Glow.apiRemoveReaction(message.id, emoji);
} else {
await Glow.apiAddReaction(message.id, emoji);
}
const data = await Glow.apiGetMessageReactions(message.id);
message.reactions = data.reactions || [];
Glow.updateMessageReactionsDom?.(message.id, message.reactions);
Glow.renderReactionPopupUsers(message.reactions);
Glow.highlightReactionSelection();
if (Glow.state.activeView === "feed") {
Glow.loadFeed?.();
}
} catch (error) {
Glow.showToast(error.message || "Could not update reaction.", "error");
}
};
Glow.openReactionPopup = async message => { Glow.openReactionPopup = async message => {
Glow.reactions.activeMessage = message; Glow.reactions.activeMessage = message;
Glow.reactions.selectedIndex = 0;
const grid = Glow.els.reactionPopupGrid; const grid = Glow.els.reactionPopupGrid;
const list = Glow.els.reactionPopupList; const list = Glow.els.reactionPopupList;
@ -53,38 +97,21 @@ Glow.openReactionPopup = async message => {
grid.replaceChildren(); grid.replaceChildren();
list.replaceChildren(); list.replaceChildren();
for (const emoji of Glow.reactions.emojis) { Glow.reactions.emojis.forEach((emoji, index) => {
const button = document.createElement("button"); const button = document.createElement("button");
button.className = "reaction-popup-button"; button.className = "reaction-popup-button";
button.type = "button"; button.type = "button";
button.textContent = emoji; button.textContent = emoji;
button.setAttribute("aria-label", `React with ${emoji}`);
button.addEventListener("click", async () => { button.addEventListener("click", async () => {
try { Glow.reactions.selectedIndex = index;
const existing = (message.reactions || []).find(item => item.emoji === emoji); Glow.highlightReactionSelection();
await Glow.activateReactionAtIndex(index);
if (existing?.reacted) {
await Glow.apiRemoveReaction(message.id, emoji);
} else {
await Glow.apiAddReaction(message.id, emoji);
}
const data = await Glow.apiGetMessageReactions(message.id);
message.reactions = data.reactions || [];
Glow.updateMessageReactionsDom?.(message.id, message.reactions);
Glow.renderReactionPopupUsers(message.reactions);
if (Glow.state.activeView === "feed") {
Glow.loadFeed?.();
}
} catch (error) {
Glow.showToast(error.message || "Could not update reaction.", "error");
}
}); });
grid.append(button); grid.append(button);
} });
try { try {
const data = await Glow.apiGetMessageReactions(message.id); const data = await Glow.apiGetMessageReactions(message.id);
@ -99,12 +126,26 @@ Glow.openReactionPopup = async message => {
Glow.renderReactionPopupUsers(message.reactions || []); Glow.renderReactionPopupUsers(message.reactions || []);
Glow.els.reactionPopupOverlay?.classList.remove("hidden"); Glow.els.reactionPopupOverlay?.classList.remove("hidden");
Glow.highlightReactionSelection();
setTimeout(() => { setTimeout(() => {
Glow.els.reactionCustomInput?.focus(); const first = grid.querySelector(".reaction-popup-button");
first?.focus();
}, 0); }, 0);
}; };
Glow.moveReactionSelection = delta => {
const total = Glow.reactions.emojis.length;
if (!total) return;
Glow.reactions.selectedIndex =
(Glow.reactions.selectedIndex + delta + total) % total;
Glow.highlightReactionSelection();
const grid = Glow.els.reactionPopupGrid;
const selected = grid?.querySelectorAll(".reaction-popup-button")[Glow.reactions.selectedIndex];
selected?.scrollIntoView({ block: "nearest", inline: "nearest" });
};
Glow.renderReactionPopupUsers = reactions => { Glow.renderReactionPopupUsers = reactions => {
const list = Glow.els.reactionPopupList; const list = Glow.els.reactionPopupList;
if (!list) return; if (!list) return;
@ -128,19 +169,12 @@ Glow.renderReactionPopupUsers = reactions => {
title.innerHTML = `<strong>${reaction.emoji} ${reaction.count}</strong>`; title.innerHTML = `<strong>${reaction.emoji} ${reaction.count}</strong>`;
section.append(title); section.append(title);
for (const user of reaction.users || []) { const names = document.createElement("div");
const row = document.createElement("div"); names.className = "reaction-popup-user";
row.className = "reaction-popup-user"; names.textContent = (reaction.users || [])
.map(user => user.username)
const left = document.createElement("span"); .join(", ");
left.textContent = user.username; section.append(names);
const right = document.createElement("span");
right.textContent = new Date(user.created_at).toLocaleString();
row.append(left, right);
section.append(row);
}
list.append(section); list.append(section);
} }
@ -148,6 +182,7 @@ Glow.renderReactionPopupUsers = reactions => {
Glow.closeReactionPopup = () => { Glow.closeReactionPopup = () => {
Glow.reactions.activeMessage = null; Glow.reactions.activeMessage = null;
Glow.reactions.selectedIndex = 0;
if (Glow.els.reactionCustomInput) { if (Glow.els.reactionCustomInput) {
Glow.els.reactionCustomInput.value = ""; Glow.els.reactionCustomInput.value = "";
} }
@ -163,4 +198,49 @@ Glow.els.reactionCustomInput?.addEventListener("keydown", event => {
event.preventDefault(); event.preventDefault();
Glow.submitCustomReaction?.(); Glow.submitCustomReaction?.();
} }
if (event.key === "Escape") {
event.preventDefault();
Glow.closeReactionPopup?.();
}
}); });
document.addEventListener("keydown", async event => {
if (Glow.els.reactionPopupOverlay?.classList.contains("hidden")) return;
if (event.key === "ArrowRight") {
event.preventDefault();
Glow.moveReactionSelection(1);
return;
}
if (event.key === "ArrowLeft") {
event.preventDefault();
Glow.moveReactionSelection(-1);
return;
}
if (event.key === "ArrowDown") {
event.preventDefault();
Glow.moveReactionSelection(4);
return;
}
if (event.key === "ArrowUp") {
event.preventDefault();
Glow.moveReactionSelection(-4);
return;
}
if (event.key === "Enter") {
const active = document.activeElement;
if (active === Glow.els.reactionCustomInput) return;
event.preventDefault();
await Glow.activateReactionAtIndex(Glow.reactions.selectedIndex);
return;
}
if (event.key === "Escape") {
event.preventDefault();
Glow.closeReactionPopup?.();
}
});