您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
煎蛋吐槽记录器,自动记录发送过的主题和评论
当前为
// ==UserScript== // @name jandan-recorder // @namespace yunyuyuan/jandan-recorder // @version 0.0.1 // @author monkey // @description 煎蛋吐槽记录器,自动记录发送过的主题和评论 // @license MIT // @match *://*.jandan.net/* // @grant GM_addStyle // ==/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("一条都没有,赶快去吐槽吧!"); } } (() => { 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 = window.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 = window.jQuery || window.$ || 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 (window.axios) { window.axios.interceptors.response.use((response) => { const requestData = {}; response.config.data.forEach(function(value, key) { requestData[key] = value; }); const callback = getCallback(response.config.url, requestData); callback(response.data); return response; }); } initUI(); storageInit(); } })(); })();