Twitter media-only filter toggle.

Toggle non-media tweets on and off, for the power-viewer!

Από την 26/04/2021. Δείτε την τελευταία έκδοση.

// ==UserScript==
// @name         Twitter media-only filter toggle.
// @version      0.7
// @description  Toggle non-media tweets on and off, for the power-viewer!
// @author       Cro
// @match        https://twitter.com/*
// @run-at       document-idle
// @grant        GM_setValue
// @grant        GM_getValue
// @namespace https://greatest.deepsurf.us/users/10865
// ==/UserScript==
/* jshint esversion: 6 */

(function() {
    'use strict';
    let storageKey = "cro-media-toggle";
    // The complexity of determining what is a meaningful image post.
    let containsImage = function(node)
    {
        let res = false;
        node.querySelectorAll("img").forEach(function (sub)
                                             {
            if (!(sub.src.startsWith("https://abs-0.twimg.com/emoji") ||
                  sub.src.startsWith("https://pbs.twimg.com/profile_images") ||
                  sub.src.startsWith("https://abs.twimg.com/hashflags")))
            {
                res = true;
            }
        });
        return res;
    };
    let isTarget = node => node.tagName &&
        node.tagName.toLowerCase() == "article" &&
        !(node.querySelector("video") || containsImage(node));
    let hideIfTarget = function(node) { if (isTarget(node)) node.parentNode.parentNode.parentNode.style.display = "none"; };
    let show = function(node) { node.parentNode.parentNode.parentNode.style.display = "block"; };
    let hideAll = function() { document.body.querySelectorAll("article").forEach(hideIfTarget); };
    let showAll = function() { document.body.querySelectorAll("article").forEach(show); };
    let running = GM_getValue(storageKey);

    let createUi = function(target)
    {
        let button = document.createElement("button");
        let setButtonState = function()
        {
            if (running)
            {
                button.innerText = "Only Media Tweets";
            }
            else
            {
                button.innerText = "All Tweets";
                showAll();
            }
        };

        button.onclick = function(event)
        {
            running = !running;
            GM_setValue(storageKey, running);
            setButtonState();
        };

        target.prepend(button);
        setButtonState();
    };

    let startProcess = function()
    {
        setInterval(function()
        {
            if (running && !location.pathname.startsWith("/notifications"))
            {
                hideAll();
            }
        }, 250);
    };

    // Wait for twitter's react crap finish loading things.
    let scanInterval = setInterval(function()
    {
        let target = document.body.querySelector("h1[role='heading']");
        if (target)
        {
            clearInterval(scanInterval);
            startProcess(target);
            createUi(target);
        }
    }, 10);
})();