// ==UserScript==
// @name 煎蛋吐槽记录器
// @namespace yunyuyuan/jandan-recorder
// @version 0.0.2
// @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();
}
})();
})();