feature: reactions

This commit is contained in:
Andy Burke 2025-10-15 17:50:48 -07:00
parent b8467ec870
commit 7046bb0389
11 changed files with 371 additions and 133 deletions

View file

@ -54,44 +54,50 @@ const reactions_popup_styling = `
background: inherit;
}
`;
function get_best_coords_for_popup(target, offset = { x: 10, y: 10 }) {
const target_x = target?.getBoundingClientRect().left ?? 0;
const target_y = target?.getBoundingClientRect().top ?? 0;
const viewport_width = document.body.getBoundingClientRect().width;
const viewport_height = document.body.getBoundingClientRect().height;
const best_coords = {
x: target_x + offset.x,
y: target_y + offset.y,
};
if (target_x + offset.x + reactions_popup_width + offset.x > viewport_width) {
best_coords.x = Math.max(0, target_x - reactions_popup_width);
}
if (target_y + offset.y + reactions_popup_height + offset.y > viewport_height) {
best_coords.y = Math.max(0, target_y - reactions_popup_height);
}
return best_coords;
.reaction-container {
display: inline-block;
border: 1px solid var(--border-subtle);
border-radius: var(--border-radius);
margin-right: 0.5rem;
padding: 0.25rem;
font-size: large;
}
@media screen and (max-width: 480px) {
#reactionspopup {
left: 0 !important;
right: 0 !important;
bottom: 0 !important;
top: auto !important;
width: 100% !important;
}
}
`;
let reactions_popup;
let reactions_popup_form;
let reactions_popup_search_input;
let reactions_popup_parent_id_input;
let reactions_popup_emojis_list;
let reactions_popup_reaction_input;
function open_reactions_popup(event) {
const parent_event_id = event.target?.closest("[data-event_id]")?.dataset?.event_id;
const parent_event_id =
event.target?.closest("[data-current_event_id]")?.dataset?.current_event_id;
reactions_popup_parent_id_input.value = parent_event_id ?? "";
const position = get_best_coords_for_popup(event.target.closest("[data-reactions]"), {
x: 25,
y: 25,
const position = get_best_coords_for_popup({
target_element: event.target.closest("[data-reactions]"),
popup: {
width: reactions_popup_width,
height: reactions_popup_height,
},
offset: {
x: 25,
y: 25,
},
});
reactions_popup.style.left = position.x + "px";
@ -100,6 +106,8 @@ function open_reactions_popup(event) {
reactions_popup.style.visibility = "visible";
reactions_popup.style.opacity = "1";
reactions_popup.style.display = "block";
reactions_popup_search_input.focus();
}
function clear_reactions_popup() {
@ -129,8 +137,8 @@ document.addEventListener("DOMContentLoaded", () => {
id="reactions-selection-form"
data-smart="true"
method="POST"
on_reply="async (event) => { await document.querySelectorAll( '[data-feed]' ).forEach((feed) => feed.__render(event)); }"
on_parsed="async (event) => { await document.querySelectorAll( '[data-feed]' ).forEach((feed) => feed.__render(event)); }"
on_reply="async (event) => { clear_reactions_popup(); await document.querySelectorAll( '[data-feed]' ).forEach((feed) => feed.__render(event)); }"
on_parsed="async (event) => { clear_reactions_popup(); await document.querySelectorAll( '[data-feed]' ).forEach((feed) => feed.__render(event)); }"
>
<input id="reactions-search-input" name="search" type="text" placeholder="Search..." data-skip="true" />
@ -193,6 +201,7 @@ document.addEventListener("DOMContentLoaded", () => {
: "";
});
reactions_popup_search_input = document.getElementById("reactions-search-input");
reactions_popup_parent_id_input = reactions_popup_form.querySelector('[name="parent_id"]');
reactions_popup_emojis_list = document.getElementById("reactions-emojis-list");
reactions_popup_reaction_input = reactions_popup_form.querySelector('[name="data.reaction"]');
@ -216,14 +225,14 @@ document.addEventListener("DOMContentLoaded", () => {
: "";
});
const reactions_popup_search = debounce((event) => {
const debounced_search = debounce((event) => {
const prompt = event.target?.value;
const filtered = EMOJIS.autocomplete(prompt);
delete emojis_list.dataset.filtered;
delete reactions_popup_emojis_list.dataset.filtered;
if (filtered.length) {
emojis_list.dataset.filtered = true;
emojis_list.querySelectorAll("li").forEach((li) => {
reactions_popup_emojis_list.dataset.filtered = true;
reactions_popup_emojis_list.querySelectorAll("li").forEach((li) => {
if (filtered.some((entry) => entry[0] === li.dataset.emoji)) {
li.dataset.filtered = true;
} else {
@ -233,17 +242,16 @@ document.addEventListener("DOMContentLoaded", () => {
}
}, 200);
document
.getElementById("reactions-search-input")
.addEventListener("input", reactions_popup_search);
document
.getElementById("reactions-search-input")
.addEventListener("paste", reactions_popup_search);
document
.getElementById("reactions-search-input")
.addEventListener("change", reactions_popup_search);
reactions_popup_search_input.addEventListener("input", debounced_search);
reactions_popup_search_input.addEventListener("paste", debounced_search);
reactions_popup_search_input.addEventListener("change", debounced_search);
document.querySelector("body").addEventListener("click", (event) => {
const is_in_the_reactions_form = event?.target?.closest("#reactionspopup");
if (is_in_the_reactions_form) {
return;
}
const is_a_data_reactions_child = event?.target?.closest("[data-reactions]");
if (!is_a_data_reactions_child) {
clear_reactions_popup();