// ==UserScript==
// @name bgm相关回复跳转
// @version 0.5
// @description 在web自动识别贴贴过的帖子,提供跳转。
// @match https://bgm.tv/ep/*
// @match https://bangumi.tv/ep/*
// @match https://chii.in/ep/*
// @grant none
// @license MIT
// @namespace bgm_jump_related_post
// @require https://cdn.tailwindcss.com
// @downloadURL none
// ==/UserScript==
// 几个todo,目前自己没这个需求,暂时简化。如果有人需要可以说一声:
// - [ ] 除了贴贴也支持回复过的跳转。
// 前期主要支持贴贴跳转
// 后续会增加回复跳转的,因为其实可以搜索,相对没那么着急
// - [ ] 暂时只支持番剧吐槽页面,主要是觉得别的页面也没必要。
// - [x] 暂时只处理每层回复的一楼,这个主要是暂时懒得做先简化一下。也就是不支持比如说第二楼的所有回复贴贴。
// - [ ] 看要不要支持这个框可拖动,要不就是现在这个折叠之后的样式有点小奇怪,就是不应该留东西太外面,这个动画有点太花哨了。整体其实可以更简单一点,写到后面有点后悔了,引入样式库其实已经是极限了,后续应该更精简一点
(function () {
'use strict';
// Load Tailwind CSS
const tailwindScript = document.createElement('script');
tailwindScript.src = 'https://cdn.tailwindcss.com';
document.head.appendChild(tailwindScript);
const selfUserId = $('.avatar').attr('href').split('/').pop();
// 先完成遍历处理第一层的逻辑
const replyList = $('#comment_list>div'); // 得到所有首层回复
let relatedPostIds = []; // 筛选最终跟当前用户相关的id
// replyList.slice(0, 2).each(function () { // 调试场景只看前三个帖子
replyList.each(function () { // 逐个过滤
const firstLevelId = $(this).attr('id');
// 检查一楼
if (checkReplyElementRelated(selfUserId, $(this))) {
relatedPostIds.push(firstLevelId);
}
// 检查楼中楼(二级回复)
const subReplies = $(this).find('.topic_sub_reply .sub_reply_bg');
subReplies.each(function() {
if (checkSubReplyRelated(selfUserId, $(this))) {
const subReplyId = $(this).attr('id');
relatedPostIds.push(subReplyId);
}
});
});
// console.log(relatedPostIds);
const component = createJumpComponent(relatedPostIds);
const columnEPB = $('#columnEpB')
columnEPB.append(component);
// Initialize component behavior after DOM insertion
initializeComponent(relatedPostIds);
})();
// 检查当前回复元素的「贴贴」里边是否包含当前用户id
function checkReplyElementRelated(userId, element) {
// 先在这个元素内继续选择 `a.item.selected`
// const likesGridItem = element.find('a.item.selected');
const innerDiv = element.children().eq(2)
// 这个元素里的 title 包含所有 贴贴元素的 HTML 文本,每个 `` 就是一种类型的贴贴
const likesGridItemAs = innerDiv.find('.reply_content').children().eq(1).children();
if (likesGridItemAs.length === 0) {
return false;
}
let found = false;
likesGridItemAs.each(function () {
const title = $(this).attr('title');
if (checkUserIdInTitle(userId, title)) {
found = true;
return false; // break loop
// ! 这里才是坑,里边有个回调函数,return true 会直接返回到这个回调函数,而不是外层的函数
}
});
return found;
}
function checkUserIdInTitle(userId, title) {
const regex = /\/user\/(\w+)/g;
let match;
while ((match = regex.exec(title)) !== null) {
if (match[1] === userId) {
return true;
}
}
return false;
}
// 检查楼中楼(二级回复)是否包含当前用户的贴贴
function checkSubReplyRelated(userId, element) {
// 二级回复的贴贴在 .likes_grid 中
const likesGrid = element.find('.likes_grid');
if (likesGrid.length === 0) {
return false;
}
const likesGridItems = likesGrid.find('a.item');
if (likesGridItems.length === 0) {
return false;
}
let found = false;
likesGridItems.each(function () {
const title = $(this).attr('title');
if (title && checkUserIdInTitle(userId, title)) {
found = true;
return false; // break loop
}
});
return found;
}
function createJumpComponent(postIds) {
const isEmpty = postIds.length === 0;
// Apple-inspired Bento Grid styling with Tailwind + Custom CSS
const styles = `
`;
// Generate content based on whether there are posts
let contentHtml;
let navHtml = '';
if (isEmpty) {
contentHtml = `
去给感兴趣的回复点个贴贴吧