Not a member of Pastebin yet?
                        Sign Up,
                        it unlocks many cool features!                    
                - // ==UserScript==
- // @name Hide or Highlight Verified and Seen
- // @namespace http://tampermonkey.net/
- // @version 0.3
- // @description Hides & controls visibility of verified and seen account tweets and replies.
- // @author You
- // @match https://twitter.com/*
- // @grant none
- // ==/UserScript==
- (function () {
- "use strict";
- const excludeKeywords =
- "@people,@you,@whitelist".split(
- ","
- );
- // Constants
- const seenTweetsKey = "seen_tweets";
- const maxStorageSize = 4 * 1024 * 1024; // 4MB
- const oneMonthInMilliseconds = 30 * 24 * 60 * 60 * 1000;
- // Define control panel CSS
- const generalStyle = `
- #user-script-control-panel {
- position: fixed;
- left: 20px;
- bottom: 90px;
- width: 41px; /* Set the control panel width to 23px */
- overflow: hidden; /* Hidden overflow */
- padding: 2px;
- background-color: #2D2D2D;
- color: #FFF;
- border-radius: 5px;
- box-shadow: 0 2px 5px 0 rgba(0,0,0,0.25);
- z-index: 99999999;
- }
- #user-script-control-panel:hover {
- width: auto; /* Restore the width to 200px when hovered */
- overflow: auto; /* Show the overflow when hovered */
- }
- #user-script-control-panel label {
- display: block;
- white-space: nowrap; /* Prevent text from wrapping */
- }
- #user-script-control-panel label {
- display: block; /* Make the labels (and hence checkboxes) display in a column */
- }
- .hidden-verified {
- background-color: rgba(255, 0, 0, 0.15) !important;
- }
- .hidden-seen {
- background-color: rgba(0, 207, 255, 0.15) !important;
- }
- .hidden-verified.hidden-seen {
- background: linear-gradient(90deg, rgba(0, 207, 255, 0.15) 0%, rgba(255, 0, 0, 0.15) 100%) !important;
- }
- a[rel~="noreferrer"] .css-1dbjc4n.r-161ttwi.r-u8s1d {
- display: none;
- }
- .link-text {
- display: block;
- color: white;
- background-color: #040404b5;
- font-family: "Segoe UI Emoji";
- position: relative;
- font-size: 13px;
- width: 100%;
- padding: 10px;
- padding-top: 6px;
- padding-bottom:8px;
- }
- .link-text .domain{
- color: grey;
- }
- `;
- const controlPanelHTML = `
- <div id="user-script-control-panel">
- <label>
- <input type="checkbox" id="collapseVerified"><svg viewBox="0 0 22 22" aria-label="Verified account" role="img" class="r-1cvl2hr r-4qtqp9 r-yyyyoo r-1xvli5t r-9cviqr r-f9ja8p r-og9te1 r-bnwqim r-1plcrui r-lrvibr" data-testid="icon-verified"><g><path d="M20.396 11c-.018-.646-.215-1.275-.57-1.816-.354-.54-.852-.972-1.438-1.246.223-.607.27-1.264.14-1.897-.131-.634-.437-1.218-.882-1.687-.47-.445-1.053-.75-1.687-.882-.633-.13-1.29-.083-1.897.14-.273-.587-.704-1.086-1.245-1.44S11.647 1.62 11 1.604c-.646.017-1.273.213-1.813.568s-.969.854-1.24 1.44c-.608-.223-1.267-.272-1.902-.14-.635.13-1.22.436-1.69.882-.445.47-.749 1.055-.878 1.688-.13.633-.08 1.29.144 1.896-.587.274-1.087.705-1.443 1.245-.356.54-.555 1.17-.574 1.817.02.647.218 1.276.574 1.817.356.54.856.972 1.443 1.245-.224.606-.274 1.263-.144 1.896.13.634.433 1.218.877 1.688.47.443 1.054.747 1.687.878.633.132 1.29.084 1.897-.136.274.586.705 1.084 1.246 1.439.54.354 1.17.551 1.816.569.647-.016 1.276-.213 1.817-.567s.972-.854 1.245-1.44c.604.239 1.266.296 1.903.164.636-.132 1.22-.447 1.68-.907.46-.46.776-1.044.908-1.681s.075-1.299-.165-1.903c.586-.274 1.084-.705 1.439-1.246.354-.54.551-1.17.569-1.816zM9.662 14.85l-3.429-3.428 1.293-1.302 2.072 2.072 4.4-4.794 1.347 1.246z"></path></g></svg>
- Collapse verified
- </label>
- <label>
- <input type="checkbox" id="collapseSeen">👁️
- Collapse seen
- </label>
- </div>
- `;
- document.body.insertAdjacentHTML("beforeend", controlPanelHTML);
- document.querySelector("#collapseVerified").checked =
- localStorage.getItem("collapseVerified") === "true";
- document.querySelector("#collapseSeen").checked =
- localStorage.getItem("collapseSeen") === "true";
- const controlPanel = document.querySelector("#user-script-control-panel");
- const style = document.createElement("style");
- style.innerHTML = generalStyle;
- document.head.appendChild(style);
- controlPanel.addEventListener("change", function (event) {
- localStorage.setItem(event.target.id, event.target.checked);
- updateStyles();
- processTweets();
- });
- // A throttling function that calls a function at most once every specific interval
- const throttle = (func, wait) => {
- var timeout;
- return function executedFunction() {
- var context = this;
- var args = arguments;
- var later = function () {
- timeout = null;
- func.apply(context, args);
- };
- clearTimeout(timeout);
- timeout = setTimeout(later, wait);
- };
- };
- let verifiedStyle = document.createElement("style");
- let seenStyle = document.createElement("style");
- document.head.appendChild(verifiedStyle);
- document.head.appendChild(seenStyle);
- function updateStyles() {
- verifiedStyle.innerHTML =
- localStorage.getItem("collapseVerified") === "true"
- ? `
- .hidden-verified {
- max-height: 30px !important;
- overflow: hidden;
- transition: max-height 0.3s ease;
- }
- .hidden-verified.hovered {
- max-height: unset !important;
- overflow: visible;
- }`
- : "";
- seenStyle.innerHTML =
- localStorage.getItem("collapseSeen") === "true"
- ? `
- .hidden-seen {
- max-height: 30px !important;
- overflow: hidden;
- transition: max-height 0.3s ease;
- }
- .hidden-seen.hovered {
- max-height: unset !important;
- overflow: visible;
- }`
- : "";
- }
- updateStyles();
- const getSeenTweets = () => {
- const seenTweets = localStorage.getItem(seenTweetsKey);
- return seenTweets ? JSON.parse(seenTweets) : {};
- };
- const saveSeenTweets = (seenTweets) => {
- const seenTweetsString = JSON.stringify(seenTweets);
- if (new Blob([seenTweetsString]).size > maxStorageSize) {
- const prunedTweets = pruneTweets(seenTweets);
- localStorage.setItem(seenTweetsKey, JSON.stringify(prunedTweets));
- } else {
- localStorage.setItem(seenTweetsKey, seenTweetsString);
- }
- };
- // Initialize hovered tweets session storage
- const sessionHoverKey = "session_hovered";
- sessionStorage.setItem(sessionHoverKey, JSON.stringify({}));
- /* Function to handle mouseenter event, adds the 'hovered' class and store hover state in session */
- function handleMouseEnter(e) {
- const tweetLink = e.target.querySelector('a[href*="/status/"]');
- if (tweetLink) {
- const tweetId = tweetLink.getAttribute("href").split("/").pop();
- let hoveredTweets =
- JSON.parse(sessionStorage.getItem(sessionHoverKey)) || {};
- if (!hoveredTweets[tweetId]) {
- hoveredTweets[tweetId] = true;
- sessionStorage.setItem(sessionHoverKey, JSON.stringify(hoveredTweets));
- }
- }
- var classes = e.target.className.split(" ");
- // Check if 'hovered' class already exists
- var hoveredClassExists = classes.includes("hovered");
- // If 'hovered' class is not applied, then add it
- if (!hoveredClassExists) {
- e.target.className += " hovered";
- }
- }
- function processTweets() {
- const articles = document.querySelectorAll("article");
- const seenTweets = getSeenTweets();
- let hoveredTweets =
- JSON.parse(sessionStorage.getItem(sessionHoverKey)) || {};
- observer.disconnect();
- articles.forEach((article) => {
- const tweetLink = article.querySelector('a[href*="/status/"]');
- if (tweetLink) {
- const tweetId = tweetLink.getAttribute("href").split("/").pop();
- if (hoveredTweets[tweetId] && !article.classList.contains("hovered")) {
- article.className += " hovered";
- }
- }
- if (!article.classList.contains("hidden-verified")) {
- const svg = article.querySelector('svg[aria-label="Verified account"]');
- const articleText = article.textContent.toLowerCase();
- const shouldExclude = excludeKeywords.some((keyword) =>
- articleText.includes(keyword.toLowerCase())
- );
- if (svg && !shouldExclude) {
- article.classList.add("hidden-verified");
- article.addEventListener("mouseenter", handleMouseEnter);
- }
- }
- if (!article.classList.contains("hidden-seen")) {
- if (tweetLink) {
- const tweetId = tweetLink.getAttribute("href").split("/").pop();
- if (seenTweets[tweetId]) {
- article.classList.add("hidden-seen");
- article.addEventListener("mouseenter", handleMouseEnter); // Attach mouseenter event
- }
- }
- }
- const ariaLabelModifiedClass = "aria-label-modified";
- const mediaLink = article.querySelector('div[data-testid="card.layoutLarge.media"] a[rel~="noreferrer"].r-13qz1uu');
- if (mediaLink && !mediaLink.classList.contains(ariaLabelModifiedClass)) {
- const ariaLabel = mediaLink.getAttribute("aria-label");
- if (ariaLabel) {
- const labelSplit = ariaLabel.split(/ (.+)/);
- const domain = labelSplit[0];
- const text = labelSplit.length > 1 ? labelSplit[1] : "";
- const linkTextElement = document.createElement('div');
- linkTextElement.className = 'link-text';
- const domainElement = document.createElement('div');
- domainElement.className = 'domain';
- domainElement.textContent = domain;
- linkTextElement.appendChild(domainElement);
- const titleElement = document.createElement('div');
- titleElement.className = 'title';
- titleElement.textContent = text;
- linkTextElement.appendChild(titleElement);
- mediaLink.appendChild(linkTextElement);
- // Add a class to indicate that this mediaLink has been modified
- mediaLink.classList.add(ariaLabelModifiedClass);
- }
- }
- });
- observer.observe(document, {
- childList: true,
- subtree: true,
- });
- }
- // Listen scroll event. Throttled function to avoid too many calls
- window.addEventListener(
- "scroll",
- throttle(() => {
- const articles = document.querySelectorAll("article");
- const seenTweets = getSeenTweets();
- articles.forEach((article) => {
- const rect = article.getBoundingClientRect();
- if (rect.bottom < 0) {
- const tweetLink = article.querySelector('a[href*="/status/"]');
- if (tweetLink) {
- const tweetId = tweetLink.getAttribute("href").split("/").pop();
- // Check if the tweet is verified and if verified tweets are collapsed
- const isVerified = article.classList.contains("hidden-verified");
- const collapseVerified =
- localStorage.getItem("collapseVerified") === "true";
- // Check if the tweet is not seen and either it's not verified or it's verified but not collapsed or it's hovered
- if (
- !seenTweets[tweetId] &&
- (!isVerified ||
- (isVerified && !collapseVerified) ||
- article.classList.contains("hovered"))
- ) {
- seenTweets[tweetId] = Date.now();
- saveSeenTweets(seenTweets);
- if (rect.top > 0) {
- article.classList.add("hidden-slim");
- } else {
- article.classList.add("hovered");
- }
- article.classList.add("hidden-seen");
- article.addEventListener("mouseenter", handleMouseEnter); // Attach mouseenter event, provided it doesn't already exist
- }
- }
- }
- processTweets();
- });
- }, 100)
- ); // throttle function will ensure that the function is called at most once every 100 milliseconds
- const observer = new MutationObserver(processTweets);
- observer.observe(document, {
- childList: true,
- subtree: true,
- });
- processTweets();
- })();
Advertisement
 
                    Add Comment                
                
                        Please, Sign In to add comment                    
                 
                    