diff options
| author | Jakob L. Kreuze | 2024-07-13 18:04:05 -0400 |
|---|---|---|
| committer | Jakob L. Kreuze | 2024-07-13 18:11:42 -0400 |
| commit | 81c4d517735983a5afd6e9dc800257c761598527 (patch) | |
| tree | 6b924707914d385126e6d330d2c628fd26f23a27 /haunt/static/js/comment-reaction.js | |
| parent | 7f37518e4792f040a753a5d8d68d51e76cc0b2be (diff) | |
The `org' directory is no longer necessary
Diffstat (limited to 'haunt/static/js/comment-reaction.js')
| -rw-r--r-- | haunt/static/js/comment-reaction.js | 143 |
1 files changed, 0 insertions, 143 deletions
diff --git a/haunt/static/js/comment-reaction.js b/haunt/static/js/comment-reaction.js deleted file mode 100644 index 1002fa2..0000000 --- a/haunt/static/js/comment-reaction.js +++ /dev/null @@ -1,143 +0,0 @@ -/* - * comment-reaction.js -- Simple emoji picker and glue for reaction endpoint - * Copyright © 2023 Jakob L. Kreuze <zerodaysfordays@sdf.org> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see - * <http://www.gnu.org/licenses/>. - */ - -function encodeAsFormData(obj) { - // Turn the data object into an array of URL-encoded key/value pairs. - let urlEncodedDataPairs = []; - for (let key in obj) { - urlEncodedDataPairs.push(encodeURIComponent(key) + '=' + encodeURIComponent(obj[key])); - } - return urlEncodedDataPairs.join('&'); -} - -function postReaction(reaction, callback) { - let xhr = new XMLHttpRequest(); - xhr.open('POST', "/api/comment/react", true); - - // Endpoint expects HTML form data. - xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); - - xhr.onload = function(data) { - switch (xhr.status) { - case 200: - callback(); - break; - case 429: - alert("Failed -- you can react at most once an hour."); - break; - default: - let resp = JSON.parse(xhr.response); - alert("Failed -- " + resp.error); - break; - } - } - xhr.onerror = function(error) { - throw new Error(`Request failed: ${error}`); - } - - xhr.send(encodeAsFormData(reaction)); -} - -function selectorWidgetName(id) { - return `emoji-picker-${id}`; -} - -// Simple Emoji picker widget. -function selectorWidget(id) { - function emojiButton(codepoint) { - let span = document.createElement("span"); - span.innerHTML = String.fromCodePoint(codepoint); - return span; - } - - let selector = document.createElement("div"); - selector.setAttribute("id", selectorWidgetName(id)); - selector.setAttribute("class", "emoji-picker"); - - for (let i = 0x1F600; i < 0x1F64F; i++) { - selector.appendChild(emojiButton(i)); - } - selector.appendChild(emojiButton(0x1F37B)); - selector.appendChild(emojiButton(0x1F440)); - selector.appendChild(emojiButton(0x1F446)); - selector.appendChild(emojiButton(0x1F447)); - selector.appendChild(emojiButton(0x1F448)); - selector.appendChild(emojiButton(0x1F449)); - selector.appendChild(emojiButton(0x1F450)); - selector.appendChild(emojiButton(0x270A)); - selector.appendChild(emojiButton(0x270B)); - selector.appendChild(emojiButton(0x270C)); - selector.appendChild(emojiButton(0x270D)); - for (let i = 0x1F90C; i < 0x1F9FF; i++) { - selector.appendChild(emojiButton(i)); - } - return selector; -} - -// Add a "react" button to every local comment. -window.addEventListener("load", () => { - // First pass to add a separator for the buttons. - let replyButtons = document.querySelectorAll(".comment-reply-button"); - for (let button of replyButtons) { - let parent = button.parentNode; - parent.innerHTML += " - "; - - } - - // Second pass to add the actual "react" button. - replyButtons = document.querySelectorAll(".comment-reply-button"); - for (let button of replyButtons) { - let id = button.getAttribute("data-reply-to-id"); - let reactButton = document.createElement("a"); - reactButton.setAttribute("class", "comment-react-button"); - reactButton.setAttribute("href", "#"); - reactButton.setAttribute("data-react-to-id", id); - reactButton.innerHTML = "react"; - button.parentNode.appendChild(reactButton); - - reactButton.addEventListener('click', (e) => { - // If we already made a selector widget for this comment, let's "hide" the - // one that exists. - let existingSelectorWidget = document.getElementById(selectorWidgetName(id)); - if (existingSelectorWidget !== null) { - existingSelectorWidget.remove(); - e.preventDefault(); - return; - } - - let emojiPicker = selectorWidget(id); - button.parentNode.parentNode.insertBefore(emojiPicker, button.parentNode); - for (let button of emojiPicker.children) { - button.addEventListener('click', (e) => { - postReaction({ - "id": reactButton.getAttribute("data-react-to-id"), - "reaction": button.innerHTML - }, () => { - let reactAcknowledgement = document.createElement("span"); - reactAcknowledgement.innerHTML = "successfully reacted!" - reactButton.replaceWith(reactAcknowledgement); - }); - emojiPicker.remove(); - }); - } - - e.preventDefault(); - }); - } -}); |