F95 Tag Whitelist Blacklist

Whitelist Blacklist

// ==UserScript==
// @name         F95 Tag Whitelist Blacklist
// @namespace    http://tampermonkey.net/
// @version      1.1
// @author       soc9bbmco 
// @description  Whitelist Blacklist
// @match        https://f95zone.to/threads/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=f95zone.to
// @grant        GM_registerMenuCommand
// @grant        GM_setValue
// @grant        GM_getValue
// ==/UserScript==

(function() {
    'use strict';

    let Like = GM_getValue('Like', '');
    let Dislike = GM_getValue('Dislike', '');
    const $tagList = $('span.js-tagList');

    const likeTags = [];
    const dislikeTags = [];
    const others = [];
    GM_registerMenuCommand('settings', openSettings);

    function includesAnyIgnoreCase(text, keywords) {
        if (!keywords) return false;
        const textLower = text.toLowerCase();
        return keywords.split(',').some(kw => textLower.includes(kw.trim().toLowerCase()));
    }

    $('span.js-tagList a').each(function() {
        const $this = $(this);
        const text = $this.text();
        if (includesAnyIgnoreCase(text, Like)) {
            $this.css({ 'color': '#000000', 'background-color': '#F0F0F0' });
        likeTags.push($this);
        } else if (includesAnyIgnoreCase(text, Dislike)) {
            $this.css('color', 'red');
            dislikeTags.push($this);
        }else {
            others.push($this);
        }
    });
     $tagList.empty();
    likeTags.forEach($el => $tagList.append($el).append(' '));
    dislikeTags.forEach($el => $tagList.append($el).append(' '));
    others.forEach($el => $tagList.append($el).append(' '));

    function openSettings() {
        if ($('#translationWindow').length) return;

        const translationWindow = document.createElement('div');
        translationWindow.id = 'translationWindow';
        translationWindow.style.position = 'fixed';
        translationWindow.style.top = '100px';
        translationWindow.style.left = '50%';
        translationWindow.style.transform = 'translateX(-50%)';
        translationWindow.style.background = '#272727';
        translationWindow.style.border = '1px solid #ccc';
        translationWindow.style.padding = '10px';
        translationWindow.style.zIndex = 99999;
        translationWindow.style.width = '300px';
        translationWindow.style.boxShadow = '0 0 10px rgba(0,0,0,0.5)';

        translationWindow.innerHTML = `
      <div id="dragHandle" style="cursor: move; margin-bottom:10px; font-weight:bold;color:#272727; background:#eee; padding:4px;">
        Separate with , (not case sensitive
      </div>
      <div style="display:flex; justify-content:space-between; margin-bottom:5px;">
        <label style="flex:1;color:#FFFFFF;">Like</label>
        <input id="likeInput" type="text" style="flex:2;" value="${Like}">
      </div>
      <div style="display:flex; justify-content:space-between; margin-bottom:10px;">
        <label style="flex:1;color:#FFFFFF;">Dislike</label>
        <input id="dislikeInput" type="text" style="flex:2;" value="${Dislike}">
      </div>
      <div style="display:flex; justify-content:space-between;">
        <button id="saveBtn">Save</button>
        <button id="closeBtn">Exit</button>
      </div>
    `;

      document.body.appendChild(translationWindow);

      
      makeDraggable(translationWindow, document.getElementById('dragHandle'));

      document.getElementById('saveBtn').onclick = function() {
          let likeVal = document.getElementById('likeInput').value
          .trim()
          .replace(/^,|,$/g, '') 
          .split(',')
          .map(s => s.trim()) 
          .filter(Boolean)    
          .join(',');

          let dislikeVal = document.getElementById('dislikeInput').value
          .trim()
          .replace(/^,|,$/g, '')
          .split(',')
          .map(s => s.trim())
          .filter(Boolean)
          .join(',');

          Like = likeVal;
          Dislike = dislikeVal;

          GM_setValue('Like', Like);
          GM_setValue('Dislike', Dislike);

          alert('Saved!\nlike: ' + Like + '\ndislike: ' + Dislike);
      };

      document.getElementById('closeBtn').onclick = function() {
          translationWindow.remove();
      };
  }

    function makeDraggable(elmnt, handle) {
        let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
        handle.onmousedown = dragMouseDown;

        function dragMouseDown(e) {
            e = e || window.event;
            e.preventDefault();
            pos3 = e.clientX;
            pos4 = e.clientY;
            document.onmouseup = closeDragElement;
            document.onmousemove = elementDrag;
        }

        function elementDrag(e) {
            e = e || window.event;
            e.preventDefault();
            pos1 = pos3 - e.clientX;
            pos2 = pos4 - e.clientY;
            pos3 = e.clientX;
            pos4 = e.clientY;
            elmnt.style.top = (elmnt.offsetTop - pos2) + "px";
            elmnt.style.left = (elmnt.offsetLeft - pos1) + "px";
        }

        function closeDragElement() {
            document.onmouseup = null;
            document.onmousemove = null;
        }
    }

})();