Chamie / Bash.im clean Abyss

// ==UserScript==
// @name         Bash.im clean Abyss
// @namespace    http://chamie.ru/
// @version      0.3.6
// @description  Hides all the quotes in bash.im's Abyss section that you've already voted for.
// @author       Chamie
// @match        https://bash.im/abyss*
// @grant        none
// @license      MIT
// @updateURL    https://openuserjs.org/meta/Chamie/Bash.im_clean_Abyss.meta.js
// ==/UserScript==

(function () {
  'use strict';

  const daysToPurge = 30;   // quote lifetime in days
  let reloadTimeout = 30;// how long to wait until page reload if all the quotes on it has been hidden
  const hoursShift = daysToPurge * 24;
  const now = new Date();
  let hiddenCounter = 0;
  let numberOfQuotesLeftVisible = 0;
  const voted = JSON.parse(localStorage["abyss.quotes.voted"] || "[]").filter(x => (new Date(x.date).setHours(hoursShift) > now));
  const menuBar = document.querySelector("main > div");
  menuBar.style.height = "auto";
  menuBar.innerHTML +=
    `<div style='margin-top:3px'>
				Скрыто цитат: всего
				<span id='votedCounter'>${voted.length}</span>
				<sup title='Очистить список. Цитаты старше ${daysToPurge} дней удаляются автоматически' style='cursor:pointer' onclick='localStorage[\"abyss.quotes.voted\"]=\"[]\"'>x</sup>
				, на этой странице —
				<span id='quotesHidden'>0</span>.
		</div>`;
  const hiddenCounterSpan = document.getElementById("quotesHidden");
  const totalCounterSpan = document.getElementById("votedCounter");
  
  const style = document.createElement("style");
  style.innerHTML = "@keyframes slideup{from{max-height:300px;opacity:1;margin:10px 0;}to{max-height:0;opacity:0;margin:0 0}}.quote.voted{animation:slideup .2s forwards}";
  document.head.appendChild(style);
  
  //let log = "";

  setTimeout(() => {
    document.querySelectorAll("article.quote").forEach((q,i) => {
      const id = q.dataset.quote;
      //console.log("Quote #", i, id);
      const voteHandler = () => {
        voted.push({ "id": id, "date": new Date().toISOString().split("T")[0] });
        q.classList.add("voted");
        localStorage["abyss.quotes.voted"] = JSON.stringify(voted);
        totalCounterSpan.innerHTML = voted.length;
        hiddenCounterSpan.innerHTML = ++hiddenCounter;
      };
      if (voted.some(v => v.id == id) || q.classList.contains("voted")) {
        // Handle quotes voted before installing the script:
        if(!voted.some(v => v.id == id))
          voteHandler();

        q.classList.add("voted");
        
				//log +="Спрятал" + hiddenCounter+"\n";
        //console.log("Спрятал", hiddenCounter);
        hiddenCounterSpan.innerHTML = ++hiddenCounter;
        if (hiddenCounter == 25) {
          hiddenCounterSpan.innerHTML = `все.<br>Перезагрузка страницы через <span id='reloadTimeoutSpan'>${reloadTimeout}</span> секунд`;
          const timeoutSpan = document.getElementById("reloadTimeoutSpan");
          setInterval(() => {
            timeoutSpan.innerHTML = --reloadTimeout;
            if (reloadTimeout < 1) location.reload();
          }, 1000);
        }
      } else {
        // Handle swipe voting:
        ++numberOfQuotesLeftVisible;
				//log +=`Оставил:${++numberOfQuotesLeftVisible} ${id} ${q.querySelector('.quote__body').innerHTML}`+"\n";
        //console.log("Оставил:", ++numberOfQuotesLeftVisible, id, q.querySelector('.quote__body').innerHTML);
        let x, y, t;
        q.addEventListener('touchstart', event => {
          const e = event.changedTouches[0];
          x = e.pageX;
          y = e.pageY;
          t = (new Date).getTime();
        });
        q.addEventListener('touchend', event => {
          const e = event.changedTouches[0];
          if ((new Date).getTime() - t < 300
              && Math.abs(e.pageX - x) >= 150
              && Math.abs(e.pageY - y) <= 100)
            voteHandler();
        });

        // Handle click voting:
        q.querySelectorAll(".quote__button.up,.quote__button.down,.quote__button.dismiss")
          .forEach(btn => btn.addEventListener("click", voteHandler, false));
      }
    });
  	//console.log(hiddenCounter, numberOfQuotesLeftVisible);
    if(hiddenCounter + numberOfQuotesLeftVisible !== 25) console.log(log);
  }, 100);
})();