LoveIsGrief / Hide uninteresting posts

(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
/**
 * How many times we should try and hide this shit...
 */
const MAX_HIDE_ATTEMPTS = 3;

/**
 * How long to wait before checking if something has been hidden
 * In milliseconds
 */
const HIDE_DELAY = 1000;

var getTitle = require("./thingyverse").getTitle;

/**
 * Takes care of simulating a user hiding a post
 *
 * @param href [String]
 * @param thing [HtmlElement]
 * @param attempt [Integer]
 */
module.exports = function _hideIt(href, thing, attempt = MAX_HIDE_ATTEMPTS) {
    if (attempt === MAX_HIDE_ATTEMPTS) {
        console.log("Hiding", getTitle(thing), ":", href);
    }
    return new Promise((resolve, reject) => {
        var title = getTitle(thing);
        var returnObject = {
            href: href,
            thing: thing
        }
        if (attempt-- === 0) {
            reject({href: href, thing: thing, message: `Couldn't hide ${href}`});
        } else {
            var hideAnchor = thing.querySelector("form.hide-button a");
            console.debug("Attempt " + (MAX_HIDE_ATTEMPTS - attempt) + " at hiding: ", title, href);
            window.change_state && window.change_state(hideAnchor, 'hide', window.hide_thing);
            console.debug("Setting timeout to check");
            setTimeout(() => {
                if (thing.classList.toString().includes("hidden")) {
                    resolve(returnObject);
                } else {
                    console.info("Try again", getTitle(thing), ":", href);
                    _hideIt(href, thing, attempt).then(resolve).catch((errorObject) => {
                        reject(errorObject);
                    })
                }
            }, HIDE_DELAY);
            if (hideAnchor) {
                hideAnchor.click();
            }
        }
    });
}


},{"./thingyverse":2}],2:[function(require,module,exports){
/**
 * Shit to deal with posts or "things" as they are typed with DOM .classes by reddit
 * @type {{}}
 */
module.exports = {
    getTitle: function (thing) {
        return thing.querySelector(".title a").innerHTML
    },
}
},{}],3:[function(require,module,exports){
// ==UserScript==
// @name        Hide uninteresting posts
// @namespace   com.namingthingsishard
// @description Hides posts you keep seeing, but never clicking or voting on
// @include     https://reddit.com/*
// @include     https://www.reddit.com/*
// @exclude     https://reddit.com/user/*
// @exclude     https://*.reddit.com/user/*
// @exclude     https://reddit.com/*/comments/*
// @exclude     https://*.reddit.com/*/comments/*
// @exclude     https://reddit.com/r/*/duplicates/*
// @exclude     https://*.reddit.com/r/*/duplicates/*
// @version     3.0
// @grant       GM.getValue
// @grant       GM.setValue
// ==/UserScript==

const DEBUG = false;
if (!DEBUG) {
    console.debug = function () {
    };
}
/**
 * It should be safe to assume that if you refresh a page multiple times
 * keep seeing the same content and still don't vote on it
 * that you must be disinterested in it.
 *
 */

// If you come across something this amount of times and you ain't done nothing with it well... tough luck, out it goes!
const MAX_SEEN_COUNT = 5;
const MAX_DAYS_IN_DB = 2;

var now = Date.now();

var hidePost = require("../lib/reddit/hidePost.js");
var getTitle = require("../lib/reddit/thingyverse").getTitle;

// Clean db of old posts
function dbHousekeeping(seen) {
    console.debug("cleaning house");
    var cleaned = [];
    for (var key of Object.keys(seen)) {
        var value = seen[key];
        if (value.lastSeen && value.lastSeen < (now - Date.UTC(1970, 0, MAX_DAYS_IN_DB))) {
            delete seen[key];
            cleaned.push(key);
        }
    }
    if (cleaned.length > 0) {
        console.log("Cleaned", cleaned.length, "old links");
    }
}

/**
 * Hide the things ;)
 *
 * @param thingsToHide {Object} key=href, value=thing
 * @returns {Promise<void>}
 */
async function doTheThing(thingsToHide) {
    for (let {href, thing} of thingsToHide) {
        try {
            await hidePost(href, thing);
            console.info("Hid uninteresting link", getTitle(thing), ":", href);
        } catch (e) {
            console.error("Couldn't hide uninteresting link", href, thing, getTitle(thing));
        }
    }
}

/**
 *
 * @param seen {Object} basically the db. key=href, value = object
 */
function main(seen) {
    // All posts
    var things = document.querySelectorAll(".linklisting .thing.link,.linklisting .thing.self");
    if (things.length <= 0) {
        console.log("Shit's clean yo... nothing to hide!");
        return
    }

    var possiblyUninterestingLinks = [];
    var thingsToHide = [];
    console.log("Looking for uninteresting posts in ", things.length, " items...")

    Array.prototype.forEach.call(things, (thing) => {
        var anchor = thing.querySelector("a.title");
        var href = anchor.href;

        // Don't count duplicates
        if (possiblyUninterestingLinks.includes(href)) {
            return
        }

        var dbThing = seen[href] || {timesSeen: 1};
        console.debug("Got dbThing ", dbThing);
        if (dbThing.timesSeen < MAX_SEEN_COUNT) {
            if (dbThing.timesSeen === MAX_SEEN_COUNT - 1) {
                console.info("NEXT on the chopping block!", getTitle(thing), href);
                // Mark with yellow to tell it's next
                thing.style.background = "#ffea0080";
            } else {
                console.debug("Seen", href, "only", dbThing.timesSeen);
            }
            dbThing.timesSeen++;
            dbThing.lastSeen = now;
            seen[href] = dbThing;
            possiblyUninterestingLinks.push(href);
        } else {
            // Just hide it, so we don't have to see its ugly mug!
            thing.style.display = "none";
            // Mark with red to show we're gonna delete 'em
            thing.style.background = "#f006";
            thingsToHide.push({href, thing});
        }
    })

    GM.setValue("seen", seen).then(() => console.info("updated DB"));
    // console.log("Possibly", possiblyUninterestingLinks.length, " things here");
    // noinspection JSIgnoredPromiseFromCall
    doTheThing(thingsToHide);
}

// Manage the DB ourselves
var seen = GM.getValue("seen", {}).then((seen) => {
    dbHousekeeping(seen);
    main(seen);
});

},{"../lib/reddit/hidePost.js":1,"../lib/reddit/thingyverse":2}]},{},[3]);