Update static/js/10-reactions.js
This commit is contained in:
parent
b85df7fdbd
commit
ead6a4f709
@ -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?.();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
Loading…
x
Reference in New Issue
Block a user