您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
为Twitter增加两个按钮,快速让Twitter算法知道你“不感兴趣的推文“ From Chrome Extension "Make Twitter Great Again" not interesting this post
- // ==UserScript==
- // @name Make Twitter Great Again
- // @namespace https://github.com/androidcn/userscripts/
- // @version 2024-12-25
- // @description 为Twitter增加两个按钮,快速让Twitter算法知道你“不感兴趣的推文“ From Chrome Extension "Make Twitter Great Again" not interesting this post
- // @author theopenprojects.io
- // @match https://twitter.com/home
- // @match https://x.com/home
- // @icon https://www.google.com/s2/favicons?sz=64&domain=twitter.com
- // @grant GM_setValue
- // @grant GM_getValue
- // @license MIT
- // ==/UserScript==
- var hideButton = document.createElement('button');
- function createButton() {
- // Create a button element
- hideButton.textContent = '隐藏';
- hideButton.style.position = 'fixed';
- hideButton.style.top = '60px';
- hideButton.style.right = '20px';
- hideButton.style.zIndex = '9999';
- // Append the button to the body
- document.body.appendChild(hideButton);
- // Add click event listener to the button
- hideButton.addEventListener('click', performHidedAction);
- }
- function hideIt(){
- document.querySelector("header[role='banner']").style="display:none;";
- document.querySelector('div[aria-label="Home timeline"] div:first-child').style="display:none;";
- //console.log('已隐藏');
- hideButton.textContent = '显示';
- //GM_setValue("leftSideBar_hide",true);
- }
- function showIt(){
- document.querySelector("header[role='banner']").style="";
- document.querySelector('div[aria-label="Home timeline"] div:first-child').style="";
- //console.log('已显示');
- hideButton.textContent = '隐藏';
- //GM_setValue("leftSideBar_hide",false);
- }
- function performHidedAction() {
- var HideText = hideButton.textContent ;
- if (HideText == "隐藏"){
- hideIt();
- }
- else{
- showIt();
- }
- }
- // Wait for the page to load
- window.addEventListener('load', createButton);
- //Scroll to hide lefe bar and top bar
- //window.addEventListener('scroll',hideIt);
- const silencePath = 'path[d="M18 6.59V1.2L8.71 7H5.5C4.12 7 3 8.12 3 9.5v5C3 15.88 4.12 17 5.5 17h2.09l-2.3 2.29 1.42 1.42 15.5-15.5-1.42-1.42L18 6.59zm-8 8V8.55l6-3.75v3.79l-6 6zM5 9.5c0-.28.22-.5.5-.5H8v6H5.5c-.28 0-.5-.22-.5-.5v-5zm6.5 9.24l1.45-1.45L16 19.2V14l2 .02v8.78l-6.5-4.06z"]'
- const shitPath = 'path[d="M9.5 7c.828 0 1.5 1.119 1.5 2.5S10.328 12 9.5 12 8 10.881 8 9.5 8.672 7 9.5 7zm5 0c.828 0 1.5 1.119 1.5 2.5s-.672 2.5-1.5 2.5S13 10.881 13 9.5 13.672 7 14.5 7zM12 22.25C6.348 22.25 1.75 17.652 1.75 12S6.348 1.75 12 1.75 22.25 6.348 22.25 12 17.652 22.25 12 22.25zm0-18.5c-4.549 0-8.25 3.701-8.25 8.25s3.701 8.25 8.25 8.25 8.25-3.701 8.25-8.25S16.549 3.75 12 3.75zM8.947 17.322l-1.896-.638C7.101 16.534 8.322 13 12 13s4.898 3.533 4.949 3.684l-1.897.633c-.031-.09-.828-2.316-3.051-2.316s-3.021 2.227-3.053 2.322z"]'
- const moreProfilePath = 'path[d="M3 12c0-1.1.9-2 2-2s2 .9 2 2-.9 2-2 2-2-.9-2-2zm9 2c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm7 0c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2z"]'
- const sleep = ms => new Promise(r => setTimeout(r, ms));
- const waitForElm = (selector) => {
- return new Promise((resolve, reject) => {
- const observer = new MutationObserver((mutations) => {
- mutations.forEach((mutation) => {
- const elm = mutation.target.querySelector(selector);
- if (elm) {
- observer.disconnect();
- resolve(elm);
- }
- });
- });
- observer.observe(document.body, {
- childList: true,
- subtree: true,
- });
- });
- };
- const setTabStatusToBody = () => {
- const body = document.querySelector('body')
- if (!body || !document.querySelectorAll('[role="tablist"] [role="tab"]')) return
- //if (document.URL !== 'https://twitter.com/home') return;
- if (!Array.from(document.querySelectorAll('[role="tablist"] [role="tab"][data-index]')).length > 0) Array.from(document.querySelectorAll('[role="tablist"] [role="tab"]')).map((el, idx) => el.closest('div').setAttribute('data-index', idx + 1))
- const selectedIndexElm = document.querySelector('[role="tablist"] [role="tab"][aria-selected="true"]')
- if (selectedIndexElm) {
- const parent = selectedIndexElm.closest('div')
- if (parent) {
- body.setAttribute('data-make-twitter-great-again', parent.getAttribute('data-index'))
- }
- }
- }
- const createShityBtn = (tweet) => {
- if (!tweet || tweet.querySelector('.shitBtn')) return;
- //if (document.URL !== 'https://twitter.com/home') return;
- const button = document.createElement('button');
- tweet.setAttribute('data-shit', true);
- button.classList.add('shitBtn');
- button.innerHTML = '没兴趣';
- const navAction = tweet.querySelector('div[role="group"][id*="id__"]');
- if (navAction) navAction.appendChild(button);
- }
- const createSilenceBtn = tweet => {
- if (!tweet || tweet.querySelector('.silenceBtn')) return;
- // if (document.URL !== 'https://twitter.com/home') return;
- const button = document.createElement('button');
- tweet.setAttribute('data-silence', true);
- button.classList.add('silenceBtn');
- button.innerHTML = '封禁';
- const navAction = tweet.querySelector('div[role="group"][id*="id__"]');
- if (navAction) navAction.appendChild(button);
- }
- const handleBtnClick = async (e, selector) => {
- const tweet = e.target.closest('article');
- document.querySelector('body').setAttribute('data-pop-open', true)
- const btnDropdown = tweet.querySelector('[aria-haspopup="menu"][role="button"][data-testid="caret"]');
- if (!btnDropdown) return
- btnDropdown.click();
- await sleep(5);
- const dropdown = document.querySelector('[data-testid="Dropdown"],[data-testid="sheetDialog"]');
- if (!dropdown) return;
- const item = dropdown.querySelector(selector)
- if (item) item.closest('[role]').click()
- btnDropdown.click();
- if (document.querySelector('body').getAttribute('data-make-twitter-great-again') !== "1" || document.querySelector('body').getAttribute('data-make-twitter-great-again') !== "2") tweet.remove()
- }
- const handleProfileBtnClick = async (e, selector) => {
- const userActions = document.querySelector('[role="main"] [data-testid="userActions"]')
- if (!userActions) return
- document.querySelector('body').setAttribute('data-pop-open', true)
- const path = userActions.querySelector(moreProfilePath);
- if (!path) return
- const btnDropdown = path.closest('div[dir]')
- if (!btnDropdown) return
- btnDropdown.click();
- await sleep(5);
- const dropdown = document.querySelector('[data-testid="Dropdown"]');
- if (!dropdown) return;
- const item = dropdown.querySelector(selector)
- if (item) item.closest('[role]').click()
- dropdown.remove()
- }
- const addBtnToTweets = () => {
- const tweets = document.querySelectorAll('[role="region"] article:not([data-shit]):not([data-silence])');
- if (tweets && tweets.length > 0) tweets.forEach(tweet => {
- createShityBtn(tweet)
- createSilenceBtn(tweet)
- });
- }
- const addProfileSilenceBtn = () => {
- const userActions = document.querySelector('[role="main"] [data-testid="userActions"]')
- if (!userActions) return
- const contentActions = userActions.parentElement
- if (!contentActions || contentActions.getAttribute('data-silence') === 'true') return
- const button = document.createElement('button');
- contentActions.setAttribute('data-silence', true);
- button.classList.add('profileSilence');
- button.innerHTML = '🤫';
- contentActions.insertBefore(button, contentActions.firstChild);
- }
- const isProfile = () => {
- if (document.querySelector('head meta[content*="twitter://user?screen_name="]')) {
- document.querySelector('body').setAttribute('data-profile', true)
- addProfileSilenceBtn()
- }
- else document.querySelector('body').removeAttribute('data-profile')
- }
- const observeTweets = () => {
- const observer = new MutationObserver((mutations) => {
- setTabStatusToBody();
- isProfile()
- if (!document.querySelector('[data-make-twitter-great-again] [role="group"] > div > [role="menu"]')) document.querySelector('body').removeAttribute('data-pop-open')
- mutations.forEach(() => addBtnToTweets());
- });
- observer.observe(document.body, {
- childList: true,
- subtree: true,
- });
- return observer;
- }
- (async () => {
- await waitForElm('[role="region"] article');
- setTabStatusToBody();
- isProfile();
- addBtnToTweets();
- document.addEventListener('click', (e) => {
- if (e.target.classList.contains('shitBtn')) handleBtnClick(e, shitPath);
- if (e.target.classList.contains('silenceBtn')) handleBtnClick(e, silencePath);
- if (e.target.classList.contains('profileSilence')) handleProfileBtnClick(e, silencePath);
- })
- const tweetsObserver = observeTweets();
- window.addEventListener('beforeunload', () => {
- tweetsObserver.disconnect();
- });
- })();