forked from andyburke/autonomous.contact
268 lines
6.8 KiB
JavaScript
268 lines
6.8 KiB
JavaScript
const reactions_popup_width = 280;
|
|
const reactions_popup_height = 280;
|
|
|
|
const reactions_popup_styling = `
|
|
#reactionspopup {
|
|
position: fixed;
|
|
width: ${reactions_popup_width}px;
|
|
height: ${reactions_popup_height}px;
|
|
z-index: 100;
|
|
background: inherit;
|
|
overflow: hidden;
|
|
border: 1px solid var(--border-normal);
|
|
padding: 0.5rem;
|
|
text-align: center;
|
|
visibility: hidden;
|
|
display: none;
|
|
opacity: 0;
|
|
}
|
|
|
|
#reactionspopup[data-shown] {
|
|
visibility: visible;
|
|
display: block;
|
|
opacity: 1;
|
|
}
|
|
|
|
#reactionspopup .icon.close {
|
|
float: right;
|
|
margin: 0.5rem;
|
|
}
|
|
|
|
#reactionspopup input[name="search"] {
|
|
width: 80%;
|
|
}
|
|
|
|
#reactionspopup ul {
|
|
margin-top: 0.5rem;
|
|
padding: 0.5rem;
|
|
text-align: left;
|
|
overflow: scroll;
|
|
}
|
|
|
|
#reactionspopup ul li {
|
|
display: inline-block;
|
|
cursor: pointer;
|
|
}
|
|
|
|
#reactionspopup ul[data-filtered] li {
|
|
display: none;
|
|
visibility: hidden;
|
|
}
|
|
|
|
#reactionspopup ul[data-filtered] li[data-filtered] {
|
|
display: inline-block;
|
|
visibility: visible;
|
|
}
|
|
|
|
#reactionspopup #reactions-names-display {
|
|
position: absolute;
|
|
left: 0;
|
|
bottom: 0;
|
|
right: 0;
|
|
height: 2rem;
|
|
background: inherit;
|
|
}
|
|
|
|
.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-current_event_id]")?.dataset?.current_event_id;
|
|
reactions_popup_parent_id_input.value = parent_event_id ?? "";
|
|
|
|
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";
|
|
reactions_popup.style.top = position.y + "px";
|
|
|
|
reactions_popup.dataset.shown = true;
|
|
reactions_popup_search_input.focus();
|
|
}
|
|
|
|
function clear_reactions_popup() {
|
|
if (!reactions_popup) {
|
|
return;
|
|
}
|
|
|
|
delete reactions_popup.dataset.shown;
|
|
}
|
|
|
|
document.addEventListener("DOMContentLoaded", () => {
|
|
if (!document.getElementById("reactions-styling")) {
|
|
const style = document.createElement("style");
|
|
style.id = "reactions-styling";
|
|
style.innerHTML = reactions_popup_styling;
|
|
document.head.appendChild(style);
|
|
}
|
|
|
|
reactions_popup = document.createElement("div");
|
|
|
|
reactions_popup.id = "reactionspopup";
|
|
reactions_popup.innerHTML = `
|
|
<div class="icon close" onclick="clear_reactions_popup()"></div>
|
|
<form
|
|
id="reactions-selection-form"
|
|
data-smart="true"
|
|
method="POST"
|
|
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" />
|
|
|
|
<input type="hidden" name="type" value="reaction" />
|
|
|
|
<input
|
|
type="hidden"
|
|
name="id"
|
|
generator="(_input, form) => 'TEMP-' + form.__submitted_at.toISOString()"
|
|
reset-on-submit
|
|
/>
|
|
<input
|
|
type="hidden"
|
|
name="meta.temp_id"
|
|
generator="(_input, form) => 'TEMP-' + form.__submitted_at.toISOString()"
|
|
reset-on-submit
|
|
/>
|
|
|
|
<input
|
|
type="hidden"
|
|
name="creator_id"
|
|
generator="() => { return APP.user?.id; }"
|
|
/>
|
|
|
|
<input
|
|
type="hidden"
|
|
name="timestamps.created"
|
|
generator="(_input, form) => form.__submitted_at.toISOString()"
|
|
reset-on-submit
|
|
/>
|
|
<input
|
|
type="hidden"
|
|
name="timestamps.updated"
|
|
generator="(_input, form) => form.__submitted_at.toISOString()"
|
|
reset-on-submit
|
|
/>
|
|
|
|
<input type="hidden" name="parent_id" reset-on-submit />
|
|
|
|
<input type="hidden" name="data.reaction" reset-on-submit />
|
|
<ul id="reactions-emojis-list">
|
|
${Object.keys(EMOJIS.MAP)
|
|
.map(
|
|
(emoji) =>
|
|
`<li data-emoji="${emoji}" data-names="${EMOJIS.MAP[emoji].map((name) => `:${name}:`).join(" ")}">${emoji}</li>`,
|
|
)
|
|
.join("\n")}
|
|
</ul>
|
|
</form>
|
|
<div id="reactions-names-display"></div>
|
|
`;
|
|
|
|
document.body.appendChild(reactions_popup);
|
|
|
|
reactions_popup_form = document.getElementById("reactions-selection-form");
|
|
APP.on("topic_changed", ({ topic_id }) => {
|
|
const reaction_topic_id = topic_id ?? document.body.dataset.topic;
|
|
reactions_popup_form.action = reaction_topic_id
|
|
? `/api/topics/${reaction_topic_id}/events`
|
|
: "";
|
|
});
|
|
|
|
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"]');
|
|
reactions_popup_names_display = document.getElementById("reactions-names-display");
|
|
|
|
reactions_popup_emojis_list.querySelectorAll("li[data-emoji]").forEach((emoji_selector) => {
|
|
emoji_selector.addEventListener("click", (event) => {
|
|
event.preventDefault();
|
|
|
|
const selector = event.target;
|
|
const emoji = selector.dataset.emoji;
|
|
|
|
reactions_popup_reaction_input.value = emoji;
|
|
reactions_popup_form.requestSubmit();
|
|
});
|
|
});
|
|
|
|
reactions_popup_form.addEventListener("mouseover", (event) => {
|
|
reactions_popup_names_display.textContent = event.target.matches("li[data-names]")
|
|
? event.target.dataset.names
|
|
: "";
|
|
});
|
|
|
|
const debounced_search = debounce((event) => {
|
|
const prompt = event.target?.value;
|
|
const filtered = EMOJIS.autocomplete(prompt);
|
|
|
|
delete reactions_popup_emojis_list.dataset.filtered;
|
|
if (filtered.length) {
|
|
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 {
|
|
delete li.dataset.filtered;
|
|
}
|
|
});
|
|
}
|
|
}, 200);
|
|
|
|
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();
|
|
return;
|
|
}
|
|
|
|
event.preventDefault();
|
|
open_reactions_popup(event);
|
|
});
|
|
});
|