E-Hentai & ExHentai Fade or hide viewed galleries and tag hider

Fade or hide viewed galleries and hide flagged tags on e-hentai and exhentai. Now working with GM4

As of 2019-04-06. See the latest version.

// ==UserScript==
// @name        E-Hentai & ExHentai Fade or hide viewed galleries and tag hider
// @namespace   https://greasyfork.org/users/25356
// @description Fade or hide viewed galleries and hide flagged tags on e-hentai and exhentai. Now working with GM4
// @version     6.0

// @include     https://exhentai.org/*
// @include     https://e-hentai.org/*

// @require https://greasemonkey.github.io/gm4-polyfill/gm4-polyfill.js
// @require	https://code.jquery.com/jquery-git.min.js



// @grant		GM.getValue
// @grant		GM.setValue
// @grant		GM_getValue
// @grant		GM_setValue
// @author      CoLdAsIcE
// ==/UserScript==

(async () => {
    'use strict';

    let $hideGal = await GM.getValue("EHXFade_hidevisited", false);

    async function isGalVisited(gid) {
        let $md = await GM.getValue("g_" + gid, 0);
        if ($md == 1) {
            return true;
        }
        return false;
    }

    async function visitGal(gid) {

        if (!await isGalVisited(gid)) {
            GM.setValue("g_" + gid, 1);
        }
    }

    function saveViewedGal() {

        if (document.URL.match(/^https?:\/\/(e-|e[^-])hentai\.org\/g\/.*$/)) { //gallery case
            //record visited galleries to local DB
            const $gal_idx = document.URL.match(/^https?:\/\/(?:e-|e[^-])hentai\.org\/g\/(\d*)\/.*$/);

            if (!isNaN($gal_idx[1])) {

               const gal_id = parseInt($gal_idx[1])

               visitGal(gal_id);
            }

        }
    }

    function fadeThumb($tag, tr=false) {

       let $p
       const $alpha = parseFloat(0.2);	
          if(tr) {
              $p = $tag.closest('tr'); 
          } else {
            	$p = $tag.closest('.gl1t'); 
          }
      
        if (isNaN($alpha))
            $alpha = '0.2';

        $p.css('opacity', $alpha);

        $p.hover(
            function () {
                $(this).stop().fadeTo('fast', 1);
            },
            function () {
                $(this).stop().fadeTo('fast', $alpha);
            }
        );
    }
  	
  
		//fades thumbnails that is divs
    async function fadeViewedGalThumb() {
        $('.itg.gld > div.gl1t').each(async function () {
          if (document.URL.match(/^https?:\/\/(e-|e[^-])hentai\.org\/(?!s).*$/) && self == top) { //search / index case, exclude iframe
            const $tagContainer = $(this);
            const $gallery = $(this).closest('.gl1t');
            const $gal_href = $tagContainer.closest('.gl1t').find('div.gl3t a').first().attr('href');
            const $gal_idx = $gal_href.match(/^https?:\/\/(?:e-|e[^-])hentai\.org\/g\/(\d*)\/.*$/);
            
            if (!isNaN($gal_idx[1])) {
              const gal_id = parseInt($gal_idx[1], 10);

              if (await isGalVisited(gal_id)) {
                if (!$hideGal) {
                  fadeThumb($tagContainer);
                  $gallery.show();
                  
                  //apply visited color to a tag
                  $('<style type="text/css">' +
                    '.gl1t > a:visited > div {font-weight:normal; color:#4b90eb !important; }' +
                    '</style>')
                    .appendTo("head");
                  
                } else {
                  $gallery.hide();
                }

              }

            }

          }
        });
    }
  
  	//fades anything with table
  	async function fadeViewedGalTable(compact=null) {
      const className = compact ? 'gl1c' : 'gl1m'
      const title = compact ? '.gl3c' : '.gl3m'
      
      $('table.itg > tbody > tr').each(async function () {
       
        const isAGallery = this.firstElementChild.classList[0] === className

        if (document.URL.match(/^https?:\/\/(e-|e[^-])hentai\.org\/(?!s).*$/) && self == top &&  isAGallery) { //search / index case, exclude iframe
					
          const $tagContainer = $(this);   
          const $gallery = $(this).closest('tr');      
          const $gal_href = $tagContainer.closest('tr').find(title + ' a').first().attr('href');    
          const $gal_idx = $gal_href.match(/^https?:\/\/(?:e-|e[^-])hentai\.org\/g\/(\d*)\/.*$/);
          
					
           if (!isNaN($gal_idx[1])) {
            const gal_id = parseInt($gal_idx[1], 10);

            if (await isGalVisited(gal_id)) {
              if (!$hideGal) {
                fadeThumb($tagContainer, true);
                $gallery.show();
								if (compact) {
                  //apply visited color to compact a tag
                  $('<style type="text/css">' +
                    title + ' > a:visited > div {font-weight:normal; color:#4b90eb !important; }' +
                    '</style>')
                    .appendTo("head");
                } else {
                	//apply visited color to minimal and minimal+ a tag
                  $('<style type="text/css">' +
                    title + ' > a:visited > div {font-weight:normal; color:#4b90eb !important; }' +
                    '</style>')
                    .appendTo("head");
                }
              } else {
                $gallery.hide();
              }
            }
          } 

        }
      });
    }

    //fades extended
    async function fadeViewedGalExt() {

      $('table.itg > tbody > tr').each(async function () {
        	
        if (document.URL.match(/^https?:\/\/(e-|e[^-])hentai\.org\/(?!s).*$/) && self == top) { //search / index case, exclude iframe
          
          const $tagContainer = $(this);   
          const $gallery = $(this).closest('tr');      
          const $gal_href = $tagContainer.closest('tr').find('.gl2e a').last().attr('href');    
          const $gal_idx = $gal_href.match(/^https?:\/\/(?:e-|e[^-])hentai\.org\/g\/(\d*)\/.*$/);

          if (!isNaN($gal_idx[1])) {
            const gal_id = parseInt($gal_idx[1], 10);

            if (await isGalVisited(gal_id)) {
              if (!$hideGal) {
                fadeThumb($tagContainer, true);
                $gallery.show();
                
                //apply visited color to minimal and minimal+ a tag
                $('<style type="text/css">' +
                  '.gl2e div a:visited div > div {font-weight:normal; color:#4b90eb !important; }' +
                  '</style>')
                  .appendTo("head");
              } else {
                $gallery.hide();
              }
            }
          } 
          
        } 
      });
    } 

    async function removeBadTags() {
        $('.itg.gld > div.gl1t').each(function () {

            const $blankGif = $(this).find(".gl6t")
            const $image = $(this);

            if ($blankGif.length > 0) {
                $image.hide();
            }
        });
    }

    function css() {
				if(document.URL.match(/^https?:\/\/(e-)hentai\.org/)){
           $('<style type="text/css">' +
            'div.hideGal {width:65px; height:auto; position:fixed; margin-left:-76px; background-color:#EDEBDF; color:#5C0D11; border: 1px solid #5C0D11; z-index: 10; cursor:pointer; }' +
            'div.hideGal div.tab { margin:6px; text-align: center;}' +
            '</style>').appendTo("head");
					}else{
            $('<style type="text/css">' +
            'div.hideGal {width:65px; height:auto; position:fixed; margin-left:-76px; background-color:#4F535B; color:skyblue; border: 1px solid #000000; z-index: 10; cursor:pointer; }' +
            'div.hideGal div.tab { margin:6px; text-align: center;}' +
            '</style>').appendTo("head");
          }

         
    }

    function hideVisitedGal() {

        //add a hide gallery tab
        if (!$hideGal) {
            $('div.ido').prepend('<div class="hideGal"><div class="tab" id="toggleseen">Hide</div></div>');
        } else {
            $('div.ido').prepend('<div class="hideGal"><div class="tab" id="toggleseen">Show</div></div>');
        }

        //hide or show gallery
        $('#toggleseen').parent().click(function (e) {

            $hideGal = !$hideGal;

            GM.setValue("EHXFade_hidevisited", $hideGal);

            if ($hideGal) {
                $("#toggleseen").text("Show");
            } else {
                $("#toggleseen").text("Hide");
            }

            applyChanges();

        });
    }
       
    function applyChanges() {
        fadeViewedGal();
    }
  
		const $select = $('#dms div select')

    css();
    hideVisitedGal();

    saveViewedGal();
  
  	//fade based on what viewing style is used
  	if($select.val() === 'm' || $select.val() === 'p') { //minimal
    fadeViewedGalTable();
    } else if ($select.val() === 'l') { //compact 
      fadeViewedGalTable(true);
    } else if ($select.val() === 'e') { //extended 
      fadeViewedGalExt();
    } else if ($select.val() === 't') { //thumbnail 
      fadeViewedGalThumb();
    }
  
    removeBadTags();
 
})();