您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Really ignore ignored users, and ignore users in specific topics
// ==UserScript== // @name Rllmuk Really Ignore Users // @description Really ignore ignored users, and ignore users in specific topics // @namespace https://github.com/insin/greasemonkey/ // @version 10 // @match https://rllmukforum.com/index.php* // @match https://www.rllmukforum.com/index.php* // ==/UserScript== function addStyle(css) { let $style = document.createElement('style') $style.appendChild(document.createTextNode(css)) document.querySelector('head').appendChild($style) } const USER_LINK_ID_RE = /profile\/(\d+)/ function TopicPage() { let topicId = document.body.dataset.pageid let ignoredUserIds = JSON.parse(localStorage.ignoredUserIds || '[]') let ignoredUsersInTopics = JSON.parse(localStorage.ignoredUsersInTopics || '{}') let topicIgnoredUserIds = [] if (ignoredUsersInTopics[topicId]) { topicIgnoredUserIds = ignoredUsersInTopics[topicId].users.map(user => user.id) ignoredUserIds.push(...topicIgnoredUserIds) } // Hide "You've chosen to ignore content by <ignored user>" addStyle(` .ipsComment_ignored { display: none; } `) // Hide posts containing elements which have an ignored user id as a specified // data attribute. function hidePostsByDataAttribute(elements, dataAttribute) { elements.forEach(el => { if (!ignoredUserIds.includes(el.dataset[dataAttribute])) return let post = el.closest('article.ipsComment') if (post.style.display == 'none') return post.style.display = 'none' }) } // Hide posts which quote ignored users function processQuotes(context) { hidePostsByDataAttribute( context.querySelectorAll('[data-ipsquote-userid]'), 'ipsquoteUserid' ) } // Hide posts which @-mention ignored users function processMentions(context) { hidePostsByDataAttribute( context.querySelectorAll('[data-mentionid]'), 'mentionid' ) } // Hide posts by users ignored in this specific topic function processTopicIgnoredPosts(context = document) { if (topicIgnoredUserIds.length == 0) return let postAvatarLinks = context.querySelectorAll('li.cAuthorPane_photo a') postAvatarLinks.forEach(el => { let userId = USER_LINK_ID_RE.exec(el.href)[1] if (!topicIgnoredUserIds.includes(userId)) return let post = el.closest('article.ipsComment') if (post.style.display == 'none') return post.style.display = 'none' }) } // Hide the unread comment separator if all subsequent posts are hidden function updateUnreadCommentSeparator() { let separator = document.querySelector('div.ipsUnreadBar') if (!separator) return let hasVisiblePost = false let sibling = separator.nextElementSibling while (sibling) { if (sibling.matches('article.ipsComment') && !sibling.classList.contains('ipsHide') && sibling.style.display != 'none') { hasVisiblePost = true break } sibling = sibling.nextElementSibling } separator.style.display = hasVisiblePost ? '' : 'none' } // Process all posts on the current page function processPosts(context = document) { processQuotes(context) processMentions(context) processTopicIgnoredPosts(context) } // Process initial posts processPosts() updateUnreadCommentSeparator() // Add a new button to a user's hover card to ignore them in this topic function processHoverCard($el) { if (!$el.classList.contains('ipsHovercard')) return // Create a new "Ignore In This Topic" button let $topicIgnore = document.createElement('div') $topicIgnore.className = 'ipsList_reset ipsFlex ipsFlex-ai:center ipsGap:3 ipsGap_row:0' $topicIgnore.style.marginTop = '12px' $topicIgnore.innerHTML = `<a href="#" class="ipsFlex-flex:11 ipsButton ipsButton_light ipsButton_verySmall"> Ignore In This Topic </a>` let $ignoreLink = $topicIgnore.querySelector('a') $ignoreLink.addEventListener('click', (e) => { e.preventDefault() let topicName = document.querySelector('.ipsType_pageTitle').innerText let user = { id: USER_LINK_ID_RE.exec($el.querySelector('a').href)[1], name: $el.querySelector('h2').innerText, avatar: $el.querySelector('img.ipsUserPhoto').src, } // Add the user to the ignored users config for this topic let ignoredUsersInTopics = JSON.parse(localStorage.ignoredUsersInTopics || '{}') if (ignoredUsersInTopics[topicId] == undefined) { ignoredUsersInTopics[topicId] = { name: topicName, users: [], } } ignoredUsersInTopics[topicId].name = topicName ignoredUsersInTopics[topicId].users.push(user) localStorage.ignoredUsersInTopics = JSON.stringify(ignoredUsersInTopics) // Apply the new ignored user settings ignoredUserIds.push(user.id) topicIgnoredUserIds.push(user.id) processPosts() updateUnreadCommentSeparator() // Hide the hover card $el.style.display = 'none' }) // Insert the new control into the hover card let $hoverCardButtons = $el.querySelector('.ipsList_reset') $hoverCardButtons.insertAdjacentElement('afterend', $topicIgnore) } // Watch for posts being replaced when paging new MutationObserver(mutations => mutations.forEach(mutation => { if (mutation.oldValue == 'true') { processPosts() updateUnreadCommentSeparator() } }) ).observe(document.querySelector('div.cTopic'), { attributes: true, attributeFilter: ['animating'], attributeOldValue: true, }) // Watch for new posts being loaded into the current page new MutationObserver(mutations => { mutations.forEach(mutation => mutation.addedNodes.forEach(processPosts) ) updateUnreadCommentSeparator() }).observe(document.querySelector('#elPostFeed > form'), { childList: true, }) // Watch for user hover cards being added for display new MutationObserver(mutations => { mutations.forEach(mutation => mutation.addedNodes.forEach(processHoverCard) ) }).observe(document.body, { childList: true, }) } function IgnoredUsersPage() { // Sync ignored user ids localStorage.ignoredUserIds = JSON.stringify( Array.from(document.querySelectorAll('[data-ignoreuserid]')).map(el => el.dataset.ignoreuserid ) ) // Add a new section to manage users ignored in specific topics let $mainArea = document.querySelector('#ipsLayout_mainArea') $mainArea.appendChild(document.createElement('br')) let $div = document.createElement('div') $div.className = 'ipsBox' function populateIgnoredUsersInTopics() { let ignoredUsersInTopics = JSON.parse(localStorage.ignoredUsersInTopics || '{}') $div.innerHTML = ` <h2 class="ipsType_sectionTitle ipsType_reset ipsClear">Users currently being ignored in specific topics</h2> <ol class="ipsDataList ipsGrid ipsGrid_collapsePhone ipsClear" data-role="tableRows"> </ol>` let $ol = $div.querySelector('ol') if (Object.keys(ignoredUsersInTopics).length == 0) { $ol.innerHTML = `<li class="ipsDataItem"> <div class="ipsType_light ipsType_center ipsPad"> <br> <br> You're not currently ignoring any users in specific topics. </div> </li>` } for (let [topicId, topicConfig] of Object.entries(ignoredUsersInTopics)) { for (let user of topicConfig.users) { let $li = document.createElement('li') $li.className = 'ipsDataItem ipsGrid_span6 ipsFaded_withHover' $li.innerHTML = ` <p class="ipsType_reset ipsDataItem_icon"> <a href="https://${location.host}/index.php?/profile/${user.id}" class="ipsUserPhoto ipsUserPhoto_tiny"> <img src="${user.avatar}" alt="${user.name}"> </a> </p> <div class="ipsDataItem_main"> <h4 class="ipsDataItem_title"><strong>${user.name}</strong></h4> <ul class="ipsList_inline"> <li class="ipsType_light"> in <a href="https://${location.host}/index.php?/topic/${topicId}"> ${topicConfig.name} </a> </li> <li> <a href="#" class="unignore ipsPos_middle ipsType_blendLinks"> <i class="fa fa-times-circle"></i> Stop ignoring </a> </li> </ul> </div>` $li.querySelector('a.unignore').addEventListener('click', (e) => { e.preventDefault() let ignoredUsersInTopics = JSON.parse(localStorage.ignoredUsersInTopics || '{}') if (!ignoredUsersInTopics[topicId]) return populateIgnoredUsersInTopics() let index = ignoredUsersInTopics[topicId].users.findIndex(u => u.id == user.id) if (index == -1) return populateIgnoredUsersInTopics() ignoredUsersInTopics[topicId].users.splice(index, 1) if (ignoredUsersInTopics[topicId].users.length == 0) { delete ignoredUsersInTopics[topicId] } localStorage.ignoredUsersInTopics = JSON.stringify(ignoredUsersInTopics) populateIgnoredUsersInTopics() }) $ol.appendChild($li) } } $mainArea.appendChild($div) } populateIgnoredUsersInTopics() } function UnreadContentPage() { let ignoredUserIds = JSON.parse(localStorage.ignoredUserIds || '[]') let view function getView() { let $activeViewButton = document.querySelector('a.ipsButton_primary[data-action="switchView"]') return $activeViewButton ? $activeViewButton.textContent.trim() : null } function processTopic($topic) { let $user = Array.from($topic.querySelectorAll('.ipsStreamItem_status a[href*="/profile/"]')).pop() if (!$user) return let userId = USER_LINK_ID_RE.exec($user.href)[1] if (ignoredUserIds.includes(userId)) { $topic.remove() } } /** * Process topics within a topic container and watch for a new topic container being added. * When you click "Load more activity", a new <div> is added to the end of the topic container. */ function processTopicContainer($el) { Array.from($el.querySelectorAll(':scope > li.ipsStreamItem'), processTopic) new MutationObserver((mutations) => { mutations.forEach((mutation) => { if (view != getView()) { processView() } else if (mutation.addedNodes[0].tagName === 'DIV') { processTopicContainer(mutation.addedNodes[0]) } }) }).observe($el, {childList: true}) } /** * Process topics when the view changes between Condensed and Expanded. */ function processView() { view = getView() processTopicContainer(document.querySelector('ol.ipsStream')) } processView() } function ForumPage() { let ignoredUserIds = JSON.parse(localStorage.ignoredUserIds || '[]') function processTopic($topic) { let $user = $topic.querySelector('.ipsDataItem_meta a') if (!$user) return let userId = USER_LINK_ID_RE.exec($user.href)[1] if (ignoredUserIds.includes(userId)) { $topic.remove() } } // Initial list of topics Array.from(document.querySelectorAll('ol.cTopicList > li.ipsDataItem[data-rowid]'), processTopic) // Watch for topics being replaced when paging new MutationObserver(mutations => mutations.forEach(mutation => Array.from(mutation.addedNodes).filter(node => node.nodeType === Node.ELEMENT_NODE).map(processTopic) ) ).observe(document.querySelector('ol.cTopicList'), {childList: true}) } let page if (location.href.includes('index.php?/topic/')) { page = TopicPage } else if (location.href.includes('index.php?/ignore/')) { page = IgnoredUsersPage } else if (location.href.includes('index.php?/discover/unread')) { page = UnreadContentPage } else if (location.href.includes('index.php?/forum/')) { page = ForumPage } if (page) { page() }
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址