Greasy Fork

Greasy Fork is available in English.

煎蛋吐槽记录器

煎蛋吐槽记录器,自动记录发送过的主题和评论

当前为 2024-03-04 提交的版本,查看 最新版本

// ==UserScript==
// @name         煎蛋吐槽记录器
// @namespace    yunyuyuan/jandan-recorder
// @version      0.0.4
// @author       monkey
// @description  煎蛋吐槽记录器,自动记录发送过的主题和评论
// @license      MIT
// @match        *://*.jandan.net/*
// @grant        GM_addStyle
// @grant        unsafeWindow
// ==/UserScript==

(e=>{if(typeof GM_addStyle=="function"){GM_addStyle(e);return}const d=document.createElement("style");d.textContent=e,document.head.append(d)})(" #header .nav-items .nav-item:last-of-type{display:flex}#header .nav-items .nav-item:last-of-type .jandan-record-link{cursor:pointer}#jandan-recorder-modal{display:none;position:fixed;top:0;left:0;right:0;bottom:0;z-index:99999;background:#0009}#jandan-recorder-modal .inner{background:#fff;width:70%;height:calc(100% - 100px);min-width:400px;margin:50px auto auto;padding:10px;border-radius:12px;box-shadow:0 0 12px #0003}#jandan-recorder-modal .table-container{overflow:auto;height:100%}#jandan-recorder-modal table{width:100%;border-collapse:collapse}#jandan-recorder-modal table thead{border-radius:12px 12px 0 0}#jandan-recorder-modal table thead th{padding:10px 0;font-size:16px;position:sticky;top:0;z-index:1;background:#c8c8c8}#jandan-recorder-modal table tbody td{font-size:14px;padding:8px 0;border-bottom:1px solid rgb(218,218,218);min-width:80px} ");

(function () {
  'use strict';

  const InterruptUrls = [
    /**
     * TODO 文章发布: N/A
    */
    /**
     * 创建 问答/树洞/随手拍/无聊图 : /api/comment/create
      request 
      {
        author: "",
        email: "",
        comment: "",
        comment_post_ID: ""
      }
      response string(id)
     */
    "/api/comment/create",
    /**
     * 楼中回复: /api/tucao/create
      request 
      {
        content: "",
        comment_id?: 5637737, // 树洞id
        comment_post_ID: 102312
      }
      response
      {
        "code": 0,
        "msg": "success",
        "data": {
          "comment_ID": 12039174,
          "comment_author": "xiaoc",
          "comment_content": "祝福!",
          "comment_date": "2024-03-04T15:53:55.267675774+08:00",
          "comment_date_int": 1709538835,
          "comment_post_ID": 5637795,
          "comment_parent": 102312,
          "comment_reply_ID": 0,
          "is_jandan_user": 0,
          "is_tip_user": 0,
          "vote_negative": 0,
          "vote_positive": 0
        }
      }
     */
    "/api/tucao/create"
    /**
     * BBS发布: /api/forum/posts
      request
      {
        "title": "",
        "content": "",
        "page_id": 112928
      }
     */
    // TODO "/api/forum/posts", 
    /**
     * BBS吐槽: /api/forum/replies
      request
      {
        "content": "",
        "post_id": 1282,
        "page_id": 112928
      }
     */
    // TODO "/api/forum/replies", 
  ];
  const list = [];
  const StorageKey = "jandan-recorder";
  function getList() {
    return list;
  }
  function storageInit() {
    try {
      list.splice(0, 0, ...JSON.parse(localStorage.getItem(StorageKey) || "[]"));
    } catch {
    }
  }
  function updateStorage(newItem) {
    newItem && list.push(newItem);
    localStorage.setItem(StorageKey, JSON.stringify(list));
  }
  const ModalId = "jandan-recorder-modal";
  function initUI() {
    const container = $("#header .nav-items .nav-item:last-of-type");
    const myPost = $("<a/>");
    myPost.addClass("nav-link jandan-record-link");
    myPost.text("我的吐槽");
    myPost.appendTo(container);
    const modalContainer = $("<div/>", { id: ModalId });
    const modalInner = $("<div/>", { class: "inner" });
    const tableContainer = $("<div/>", { class: "table-container" });
    const table = $("<table>");
    const headers = ["日期", "类型", "内容", "网址", "操作"];
    const headerEl = $("<thead>");
    const headerRow = $("<tr>");
    headers.forEach(function(header) {
      headerRow.append($("<th>").text(header));
    });
    headerEl.append(headerRow);
    table.append(headerEl);
    table.append($("<tbody>"));
    modalInner.append(tableContainer.append(table));
    modalContainer.append(modalInner);
    $("body").append(modalContainer);
    modalContainer.on("mousedown", () => {
      modalContainer.css("display", "none");
    });
    modalInner.on("mousedown", (e) => {
      e.stopPropagation();
    });
    myPost.on("click", () => {
      modalContainer.css("display", "block");
      renderList();
    });
  }
  function renderList() {
    const list2 = getList();
    const bodyEl = $(`#${ModalId} tbody`);
    bodyEl.empty();
    if (list2.length > 0) {
      list2.forEach(function(item, idx) {
        const row = $("<tr>");
        row.append($("<td>").text(new Date(item.timestamp).toLocaleString()));
        row.append($("<td>").text(item.isCreate ? "自己创建" : "评论吐槽"));
        row.append($("<td>").text(item.content));
        const urlCell = $("<td>");
        const link = $("<a>").attr("href", item.url).attr("target", "_blank").text("点击前往");
        urlCell.append(link);
        row.append(urlCell);
        row.append($("<td>").append($("<button>").text("删除").on("click", () => {
          list2.splice(idx, 1);
          updateStorage();
          renderList();
        })));
        bodyEl.append(row);
      });
    } else {
      bodyEl.text("一条都没有,赶快去吐槽吧!");
    }
  }
  var _unsafeWindow = /* @__PURE__ */ (() => typeof unsafeWindow != "undefined" ? unsafeWindow : void 0)();
  (() => {
    function getCallback(url, requestData) {
      return (res) => {
        let item = null;
        switch (url) {
          case "/api/comment/create":
            item = {
              url: `/t/${res}`,
              isCreate: true,
              content: requestData.comment,
              timestamp: Date.now()
            };
            break;
          case "/api/tucao/create":
            if (res.msg == "success") {
              const isPost = _unsafeWindow.location.pathname.startsWith("/p/");
              item = {
                url: isPost ? `/p/${requestData.comment_post_ID}#${res.data.comment_ID}` : `/t/${requestData.comment_id}#tucao-${res.data.comment_ID}`,
                isCreate: false,
                content: requestData.content,
                timestamp: Date.now()
              };
            }
            break;
        }
        item && updateStorage(item);
      };
    }
    const $2 = _unsafeWindow.jQuery || _unsafeWindow.$ || null;
    if ($2) {
      const originAjax = $2.ajax;
      $2.ajax = function(settings) {
        if (typeof settings == "object") {
          const url = settings.url;
          if (InterruptUrls.includes(url)) {
            const originCallback = settings.success;
            let requestData = settings.data;
            if (typeof requestData == "string") {
              const serializedObject = {};
              for (const [key, value] of new URLSearchParams(requestData)) {
                serializedObject[key] = value;
              }
              requestData = serializedObject;
            }
            const callback = getCallback(url, requestData);
            settings.success = Array.isArray(originCallback) ? originCallback.splice(0, 0, callback) : [originCallback, callback];
          }
        }
        return originAjax(...arguments);
      };
      if (_unsafeWindow.axios) {
        _unsafeWindow.axios.interceptors.response.use((response) => {
          var _a;
          const requestData = {};
          (_a = response.config.data) == null ? void 0 : _a.forEach(function(value, key) {
            requestData[key] = value;
          });
          const callback = getCallback(response.config.url, requestData);
          callback(response.data);
          return response;
        });
      }
      initUI();
      storageInit();
    }
  })();

})();