glo/static/js/10-reactions.js
2026-09-24 22:33:36 +00:00

167 lines
4.5 KiB
JavaScript

// static/js/10-reactions.js
"use strict";
window.Glow = window.Glow || {};
Glow.reactions = Glow.reactions || {
enabled: true,
emojis: ["👍", "❤️", "🔥", "😂", "🎉", "👏", "😮", "😢", "👀", "✅", "🚀", "💡"],
activeMessage: null
};
Glow.submitCustomReaction = async () => {
const message = Glow.reactions.activeMessage;
const input = Glow.els.reactionCustomInput;
if (!message || !input) return;
const emoji = input.value.trim();
if (!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);
input.value = "";
if (Glow.state.activeView === "feed") {
Glow.loadFeed?.();
}
} catch (error) {
Glow.showToast(error.message || "Could not update reaction.", "error");
}
};
Glow.openReactionPopup = async message => {
Glow.reactions.activeMessage = message;
const grid = Glow.els.reactionPopupGrid;
const list = Glow.els.reactionPopupList;
const customInput = Glow.els.reactionCustomInput;
if (!grid || !list) return;
grid.replaceChildren();
list.replaceChildren();
for (const emoji of Glow.reactions.emojis) {
const button = document.createElement("button");
button.className = "reaction-popup-button";
button.type = "button";
button.textContent = emoji;
button.addEventListener("click", async () => {
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);
if (Glow.state.activeView === "feed") {
Glow.loadFeed?.();
}
} catch (error) {
Glow.showToast(error.message || "Could not update reaction.", "error");
}
});
grid.append(button);
}
try {
const data = await Glow.apiGetMessageReactions(message.id);
message.reactions = data.reactions || [];
} catch (_) {
message.reactions = [];
}
if (customInput) {
customInput.value = "";
}
Glow.renderReactionPopupUsers(message.reactions || []);
Glow.els.reactionPopupOverlay?.classList.remove("hidden");
setTimeout(() => {
Glow.els.reactionCustomInput?.focus();
}, 0);
};
Glow.renderReactionPopupUsers = reactions => {
const list = Glow.els.reactionPopupList;
if (!list) return;
list.replaceChildren();
if (!reactions.length) {
const empty = document.createElement("div");
empty.className = "reaction-popup-user";
empty.textContent = "No reactions yet.";
list.append(empty);
return;
}
for (const reaction of reactions) {
const section = document.createElement("div");
section.className = "reaction-popup-section";
const title = document.createElement("div");
title.className = "reaction-popup-user";
title.innerHTML = `<strong>${reaction.emoji} ${reaction.count}</strong>`;
section.append(title);
for (const user of reaction.users || []) {
const row = document.createElement("div");
row.className = "reaction-popup-user";
const left = document.createElement("span");
left.textContent = user.username;
const right = document.createElement("span");
right.textContent = new Date(user.created_at).toLocaleString();
row.append(left, right);
section.append(row);
}
list.append(section);
}
};
Glow.closeReactionPopup = () => {
Glow.reactions.activeMessage = null;
if (Glow.els.reactionCustomInput) {
Glow.els.reactionCustomInput.value = "";
}
Glow.els.reactionPopupOverlay?.classList.add("hidden");
};
Glow.els.reactionCustomButton?.addEventListener("click", () => {
Glow.submitCustomReaction?.();
});
Glow.els.reactionCustomInput?.addEventListener("keydown", event => {
if (event.key === "Enter") {
event.preventDefault();
Glow.submitCustomReaction?.();
}
});