Better Twitter Monkey Edition

Low effort port of the Better Twitter Chrome Extension.

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(Tôi đã có Trình quản lý tập lệnh người dùng, hãy cài đặt nó!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name         Better Twitter Monkey Edition
// @namespace    http://tampermonkey.net/
// @version      0.2
// @description  Low effort port of the Better Twitter Chrome Extension.
// @author       me, oslego
// @match        https://twitter.com/*
// @grant        none
// @run-at document-start
// ==/UserScript==

/*
NOT MY WORK.
Code ported over from here with minimal effort lol.
https://github.com/oslego/better-twitter
*/

const userPrefs = {
    //CONFIGURE START - Flip the values from true/false depending if you want to enable the feature.
  "bt--nofame": {
    value: false,
    label: "No fame: Hide number of followers and following count",
  },
  "bt--nopopularity": {
    value: true,
    label: "No vanity: Hide number of tweet likes, retweets and replies",
  },
  "bt--nopromoted": {
    value: true,
    label: "Hide promoted tweets",
  },
  "bt--noretweets": {
    value: false,
    label: "Hide retweets"
  },
  "bt--nolikedtweets": {
    value: true,
    label: "Hide tweets liked by others"
  },
  "bt--notrends": {
    value: true,
    label: "Hide “Trends for you”",
  },
  "bt--nowtf": {
    value: true,
    label: "Hide “Who to follow”",
  },
  "bt--nofooter": {
    value: true,
    label: "Hide website footer",
  },
    //CONFIGURE END
}

const contentCSS = `
/* Hide promoted tweets */
.bt--nopromoted [aria-label^="timeline" i][aria-label$="timeline" i] div[bt-promoted],
.bt--nopromoted [aria-label^="timeline" i][aria-label$="tweets" i] div[bt-promoted] {
	display: none;
}

/* Hide someone else's liked tweets showing in timelines */
.bt--nolikedtweets [aria-label^="timeline" i][aria-label$="timeline" i] div[bt-likedtweet],
.bt--nolikedtweets [aria-label^="timeline" i][aria-label$="tweets" i] div[bt-likedtweet] {
	display: none;
}

/* Hide retweets */
.bt--noretweets [aria-label^="timeline" i][aria-label$="timeline" i] div[bt-retweet],
.bt--noretweets [aria-label^="timeline" i][aria-label$="tweets" i] div[bt-retweet] {
	display: none;
}

/* Hide "Who to Follow" from users' timelines aside from search result timelines
	 https://github.com/oslego/better-twitter/issues/12
*/
.bt--nowtf [aria-label^="timeline" i][aria-label$="timeline" i]:not([aria-label~="search" i]) div[bt-wtf],
.bt--nowtf [aria-label^="timeline" i][aria-label$="tweets" i] div[bt-wtf] {
	display: none;
}

/* Find "promoted" icons, then mark their ancestor <div> as a promoted tweet */
.bt--nopromoted path[d^="M20.75"] {
	animation: bt-marker-promoted 0s 1;
}
@keyframes bt-marker-promoted { to { outline-color: inherit } }

/* Find "retweeted" icons, then mark their ancestor <div> as a retweet */
.bt--noretweets path[d^="M23.615 15.477c-"] {
	animation: bt-marker-retweet 0s 1;
}
@keyframes bt-marker-retweet { to { outline-color: inherit } }

/* Find "liked tweet" icons next to "Someone liked" annotations, then mark their ancestor <div> as a retweet
	 The  path for "filled heart" is identical to the one used when you yourself like a tweet.
	 When the icon is used in context of the "Someone liked" annotation,
	 the host <svg> is an only child of its parent so we can differentiate on that. This is fragile.
	 FIXME: Find a way to match the tweet annotation container for "Someone liked" or "Someone retweeted".
*/
.bt--nolikedtweets svg:only-child path[d="M12 21.638h-.014C9.403 21.59 1.95 14.856 1.95 8.478c0-3.064 2.525-5.754 5.403-5.754 2.29 0 3.83 1.58 4.646 2.73.814-1.148 2.354-2.73 4.645-2.73 2.88 0 5.404 2.69 5.404 5.755 0 6.376-7.454 13.11-10.037 13.157H12z"] {
	animation: bt-marker-likedtweet 0s 1;
}
@keyframes bt-marker-likedtweet { to { outline-color: inherit } }

/* Find "Follow" buttons, then mark their ancestor <div> as a who-to-follow prompt */
.bt--nowtf [data-testid$="-follow"] {
	animation: bt-marker-wtf 0s 1;
}
@keyframes bt-marker-wtf { to { outline-color: inherit } }

/* Find the "Who to follow" container from the sidebar */
.bt--nowtf [aria-label*="who to follow" i]{
	animation: bt-marker-wtf-sidebar 0s 1;
}
@keyframes bt-marker-wtf-sidebar { to { outline-color: inherit } }

.bt--nowtf .bt-marker-wtf-sidebar {
	display: none !important;
}

/* Hide "Trends for you" box */
.bt--notrends [aria-label*="trending" i] {
	display: none !important;
}

/* Hide "Footer" box */
.bt--nofooter [aria-label="footer" i] {
	display: none !important;
}

/* Hide tweet reply count */
.bt--nopopularity [data-testid="reply"] span {
	display: none !important;
}

/* Hide tweet retweet count */
.bt--nopopularity [href$="/retweets"] span,
.bt--nopopularity [data-testid="retweet"] span,
.bt--nopopularity [data-testid="unretweet"] span {
  display: none !important;
}

/* Hide tweet like count */
.bt--nopopularity [data-testid="like"] span,
.bt--nopopularity [data-testid="unlike"] span,
/* Hide the likes count on a single tweet page, but not the Likes tab on the user profile page */
.bt--nopopularity [href$="/likes"]:not([role="tab"]) span {
	display: none !important;
}

/* Hide all profile stats from user cards */
.bt--nofame [href$="/following"],
.bt--nofame [href$="/followers"] {
	display: none !important;
}
`;




function applyPrefs() {
  Object.entries(userPrefs).forEach(([id, pref]) => {
    document.documentElement.classList.toggle(id, pref.value);
  })
}

const addGlobalStyle = (css) => {
    var head, style;
    head = document.getElementsByTagName('head')[0];
    if (!head) { return; }
    style = document.createElement('style');
    style.type = 'text/css';
    style.innerHTML = css;
    head.appendChild(style);
}


(function() {
    'use strict';

    addGlobalStyle(contentCSS);
    applyPrefs();
    document.addEventListener('animationstart', (e) => {
        switch (e.animationName) {
            case "bt-marker-likedtweet":
                e.target.closest('div:not([class])').setAttribute('bt-likedtweet', true)
                break;
            case "bt-marker-promoted":
                e.target.closest('div:not([class])').setAttribute('bt-promoted', true)
                break;
            case "bt-marker-retweet":
                e.target.closest('div:not([class])').setAttribute('bt-retweet', true)
                break;
            case "bt-marker-wtf-sidebar":
                // Mark the container's parent for the "Who To Follow" in the sidebar.
                e.target.parentNode.classList.add(e.animationName)
                break;
            case "bt-marker-wtf":
                const container = e.target.closest('div:not([class])');
                container.setAttribute('bt-wtf', true);

                // If found, mark the container for the "Who to Follow" heading
                const prevContainer = container.previousElementSibling;
                if (prevContainer.querySelector('h2')) {
                    prevContainer.setAttribute('bt-wtf', true);
                }

                // If found, mark the container for "show more" link
                const nextContainer = container.nextElementSibling;
                if (nextContainer.querySelector('[href^="/i/connect_people"]')) {
                    nextContainer.setAttribute('bt-wtf', true);
                }
                break;

        }
    });
})();