Greasy Fork

Mastodonに引用ボタンを追加する

MastodonのDeck UIにtootを引用するためのURLコピーボタンをboostボタンの隣に追加します。

目前为 2024-05-26 提交的版本。查看 最新版本

// SPDX-License-Identifier: MIT
// ==UserScript==
// @name         Mastodonに引用ボタンを追加する
// @namespace    http://www.eniehack.net/~eniehack/works/firefox-userscripts
// @version      0.1.2
// @description  MastodonのDeck UIにtootを引用するためのURLコピーボタンをboostボタンの隣に追加します。
// @author       eniehack
// @license      MIT
// @match        https://example.com/*
// @grant        none
// ==/UserScript==

const INTERVAL = 1000;

const insertBefore = (newNode, existingNode) => {
    existingNode.parentNode.insertBefore(newNode, existingNode.previousSibling);
};

const createQuoteButtonElement = () => {
  const qtBtn = document.createElement("button");
  qtBtn.setAttribute("class", "status__action-bar__button icon-button quote-icon");
  qtBtn.setAttribute("type", "button");
  qtBtn.setAttribute("style", "font-size: 18px; width: 23.1429px; height: 23.1429px; line-height: 18px;");
  qtBtn.setAttribute("aria-label", "quote");
  qtBtn.setAttribute("aria-hidden", "false");
  qtBtn.setAttribute("title","quote");
  qtBtn.setAttribute("tabindex","0");
  const quoteIcon = document.createElement("i");
  quoteIcon.setAttribute("class", "fa fa-quote-left");
  quoteIcon.setAttribute("aria-hidden", "true");
  qtBtn.appendChild(quoteIcon);
  return qtBtn;
};

const fetchPostId = (target) => {
  return target.querySelector("a.status__relative-time").href.match(/\/[0-9]+$/)[0].substring(1);
};

const generateText = (url) =>  {
  return `QT: ${url}`;
};

const copyText = (text) => {
  navigator.clipboard.writeText(text);
};

const insertQuoteButton = (targetArticle) => {
  const target = targetArticle.querySelector(".status__action-bar__button.star-icon.icon-button");
  const qtbtn = createQuoteButtonElement();
  // console.log(targetArticle)
  const postId = fetchPostId(targetArticle);
  const textareaElem = document.querySelector("textarea.autosuggest-textarea__textarea");
  qtbtn.onclick = () => {
    fetch(`https://${location.host}/api/v1/statuses/${postId}`)
      .then(res => res.json())
      .then(json => json.url)
      .then(url => generateText(url))
      .then(txt => copyText(txt));
  };
  insertBefore(qtbtn, target);
};

let timer;

timer = setInterval(() => {
    const articles = document.getElementsByTagName("article");
    for (const article of articles) {
      if (1 <= article.querySelectorAll(".quote-icon").length) continue;
      insertQuoteButton(article);
      // console.log("insertQuoteButton");
    }
  }, INTERVAL);

document.removeEventListener("unload", () => {
  clearInterval(timer);
});