feat: add reactions, bookmarks, polls modules with session remember config
Add three new feature modules (reactions, bookmarks, polls) with corresponding database tables, indexes, and router registrations. Introduce `SESSION_MAX_AGE_REMEMBER` config for extended session duration, add `get_unread_messages` template global, and include operational defaults for rate limiting and session settings in `site_settings`.
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
import { Http } from "./Http.js";
|
||||
|
||||
export class ReactionBar {
|
||||
constructor() {
|
||||
document.addEventListener("click", (event) => this.onClick(event));
|
||||
}
|
||||
|
||||
async onClick(event) {
|
||||
const addButton = event.target.closest(".reaction-add-btn");
|
||||
if (addButton) {
|
||||
event.preventDefault();
|
||||
this.togglePalette(addButton);
|
||||
return;
|
||||
}
|
||||
const trigger = event.target.closest("[data-reaction-emoji]");
|
||||
if (trigger && !trigger.disabled) {
|
||||
event.preventDefault();
|
||||
await this.react(trigger);
|
||||
return;
|
||||
}
|
||||
this.closeAllPalettes();
|
||||
}
|
||||
|
||||
togglePalette(addButton) {
|
||||
const palette = addButton.parentElement.querySelector(".reaction-palette");
|
||||
const isOpen = palette.hidden === false;
|
||||
this.closeAllPalettes();
|
||||
palette.hidden = isOpen;
|
||||
}
|
||||
|
||||
closeAllPalettes() {
|
||||
document.querySelectorAll(".reaction-palette").forEach((palette) => {
|
||||
palette.hidden = true;
|
||||
});
|
||||
}
|
||||
|
||||
async react(trigger) {
|
||||
const bar = trigger.closest(".reaction-bar");
|
||||
if (!bar) {
|
||||
return;
|
||||
}
|
||||
const type = bar.dataset.reactionType;
|
||||
const uid = bar.dataset.reactionUid;
|
||||
const emoji = trigger.dataset.reactionEmoji;
|
||||
try {
|
||||
const result = await Http.sendForm(`/reactions/${type}/${uid}`, { emoji });
|
||||
this.render(bar, result);
|
||||
} catch (error) {
|
||||
console.error("reaction failed", error);
|
||||
}
|
||||
this.closeAllPalettes();
|
||||
}
|
||||
|
||||
render(bar, result) {
|
||||
const counts = result.counts || {};
|
||||
const mine = new Set(result.mine || []);
|
||||
bar.querySelectorAll(".reaction-list .reaction-chip").forEach((chip) => {
|
||||
const emoji = chip.dataset.reactionEmoji;
|
||||
const count = counts[emoji] || 0;
|
||||
chip.querySelector(".reaction-count").textContent = count;
|
||||
chip.hidden = count === 0 && !mine.has(emoji);
|
||||
chip.classList.toggle("reacted", mine.has(emoji));
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user