aboutsummaryrefslogtreecommitdiff
path: root/haunt/static/js/comment-reaction.js
diff options
context:
space:
mode:
authorJakob L. Kreuze2024-07-13 18:04:05 -0400
committerJakob L. Kreuze2024-07-13 18:11:42 -0400
commit81c4d517735983a5afd6e9dc800257c761598527 (patch)
tree6b924707914d385126e6d330d2c628fd26f23a27 /haunt/static/js/comment-reaction.js
parent7f37518e4792f040a753a5d8d68d51e76cc0b2be (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.js143
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();
- });
- }
-});

© 2015 - 2026 Jakob L. Kreuze