// ==UserScript==
// @name f95zone tweaks
// @namespace f95zone tweaks
// @description f95zone exclude tags and min like filter
// @match https://f95zone.to/latest/
// @version 1.0
// @author 3xd_tango
// @require https://cdn.jsdelivr.net/combine/npm/@violentmonkey/dom@1,npm/@violentmonkey/ui@0.5
// @grant GM_addStyle
// @grant GM_getValue
// @grant GM_setValue
// ==/UserScript==
(function () {
'use strict';
var css_248z = ".customTags{border-radius:2px;box-shadow:0 0 0 0 transparent,0 1px 1px 0 rgba(0,0,0,.15),0 1px 2px 0 rgba(0,0,0,.15);display:inline-block;font-size:.8em;line-height:1.8em;margin:4px 4px 0 0;padding:0 6px;text-shadow:1px 1px 2px rgba(0,0,0,.75)}.selected-tags-wrap span:hover{background-color:#ba4545}.selected-tags-wrap span{background-color:#181a1d;border-radius:3px;cursor:pointer;display:inline-block;font-size:.9em;line-height:24px;margin:4px 4px 0 0;padding:0 6.66667px;transition:.2s}";
let like_limit = GM_getValue('like_limit', 200);
let dislikes = GM_getValue('dislikes', ['female protagonist', 'text based', 'mind control']);
let likes = GM_getValue('likes', [['incest', '#ff0000'], ['harem', '#0011ff']]);
function mainFilter() {
init();
return VM.createElement(VM.Fragment, null, VM.createElement("div", {
className: "filter-block"
}, VM.createElement("h4", {
className: "filter-block_title"
}, "Tags Like Limits"), VM.createElement("div", {
className: "selectize-input"
}, VM.createElement("input", {
value: like_limit,
autoComplete: "off",
style: "width: 127px;",
onChange: limitHandler
}))), VM.createElement("div", {
className: "filter-block"
}, VM.createElement("h4", {
className: "filter-block_title"
}, "Like Tags"), VM.createElement("div", {
className: "filter-block_content"
}, VM.createElement("div", {
className: "selectize-input"
}, VM.createElement("input", {
autoComplete: "off",
placeholder: "Enter a tag to filter...",
style: "width: 127px; opacity: 1; position: relative; left: 0px;",
onChange: likeHandler
})), VM.createElement("div", {
className: "selected-tags-wrap"
}, likes.map(dl => VM.createElement("span", {
onClick: tagRemoveHandler1
}, dl[0]))))), VM.createElement("div", {
className: "filter-block"
}, VM.createElement("h4", {
className: "filter-block_title"
}, "Dislike Tags"), VM.createElement("div", {
className: "filter-block_content"
}, VM.createElement("div", {
className: "selectize-input"
}, VM.createElement("input", {
autoComplete: "off",
placeholder: "Enter a tag to filter...",
style: "width: 127px; opacity: 1; position: relative; left: 0px;",
onChange: dislikeHandler
})), VM.createElement("div", {
className: "selected-tags-wrap"
}, dislikes.map(dl => VM.createElement("span", {
onClick: tagRemoveHandler
}, dl))))), VM.createElement("style", null, css_248z));
}
function init() {
const element = document.querySelectorAll('.resource-tile');
if (element[0]) {
likeFilter();
dislikeFilter();
likeLimit();
} else {
setTimeout(init, 100);
}
}
function tagRemoveHandler(event) {
dislikes = dislikes.filter(r => r !== event.target.textContent);
event.target.remove();
GM_setValue('dislikes', dislikes);
dislikeFilter();
}
function tagRemoveHandler1(event) {
likes = likes.filter(r => r[0] !== event.target.textContent);
event.target.remove();
GM_setValue('likes', likes);
likeFilter();
}
function likeHandler(event) {
let x;
do {
x = prompt('Please Enter the Color in Hex');
} while (!x.includes('#') && x === '' && x.length <= 1);
if (x !== null) {
const tag = [event.target.value, x];
likes.push(tag);
GM_setValue('likes', likes);
let node = document.createElement("SPAN");
node.onclick = tagRemoveHandler1;
node.appendChild(document.createTextNode(event.target.value));
document.querySelector('.selected-tags-wrap').append(node);
likeFilter();
}
}
function dislikeHandler(event) {
const tagName = event.target.value;
dislikes.push(tagName);
GM_setValue('dislikes', dislikes);
event.target.value = '';
let node = document.createElement("SPAN");
node.onclick = tagRemoveHandler;
node.appendChild(document.createTextNode(tagName));
document.querySelector('.selected-tags-wrap').append(node);
dislikeFilter();
}
function limitHandler(event) {
like_limit = event.target.value;
GM_setValue('like_limit', like_limit);
likeLimit();
}
function likeFilter() {
const element = document.querySelectorAll('.resource-tile');
document.querySelectorAll('.customTags').forEach(e => e.remove());
for (let i = 0; i < element.length; i++) {
console.debug(element[i]);
if (element[i].style.display === 'none') {
continue;
}
let node = document.createElement("DIV");
const dataTags = element[i].dataset.tags.split(',');
node.style.padding = '.5rem 0';
for (let j = likes.length - 1; j >= 0; j--) {
if (dataTags.includes(likes[j][0])) {
let node1 = document.createElement("SPAN");
node1.classList.add('customTags');
node1.style.backgroundColor = likes[j][1];
element[i].style.boxShadow = `0px 0px 10px 1px ${likes[j][1]}`;
node1.appendChild(document.createTextNode(likes[j][0]));
node.appendChild(node1);
element[i].setAttribute('isDisplay', 'true');
} else if (element[i].getAttribute('isDisplay') === null) {
element[i].setAttribute('isDisplay', 'false');
}
}
if (element[i].style.display !== 'none') {
try {
element[i].childNodes[0].childNodes[1].childNodes[1].appendChild(node);
} catch (e) {
console.error(e);
likeFilter();
}
}
}
}
function dislikeFilter() {
const element = document.querySelectorAll('.resource-tile');
for (let i = 0; i < element.length; i++) {
const dataTags = element[i].dataset.tags.split(',');
const isFP = checkTags(element[i], dataTags);
if (isFP) {
element[i].style.setProperty("display", "block", "important");
element[i].style.setProperty("height", "unset", "important");
element[i].style.setProperty("margin", "unset", "important");
} else {
element[i].style.setProperty("display", "none", "important");
element[i].style.setProperty("height", "0px", "important");
element[i].style.setProperty("margin", "0px", "important");
}
}
}
function likeLimit() {
const element = document.querySelectorAll('.resource-tile');
if (like_limit === '') {
like_limit = -1;
}
for (let i = 0; i < element.length; i++) {
const element_likes = element[i].childNodes[0].childNodes[1].childNodes[1].childNodes[1].childNodes[1].innerHTML;
if (Number(element_likes) <= Number(like_limit)) {
if (element[i].getAttribute('isDisplay') === 'false') {
element[i].style.setProperty('display', 'none', 'important');
element[i].style.setProperty('height', '0px', 'important');
element[i].style.setProperty('margin', '0px', 'important');
}
} else {
element[i].style.setProperty("display", "block", "important");
element[i].style.setProperty("height", "unset", "important");
element[i].style.setProperty("margin", "unset", "important");
}
}
}
function checkTags(element, dataTags) {
let tagProt = ['female protagonist', 'male protagonist', 'futa/trans protagonist'];
const tagProtNames = dislikes.filter(e => e.includes('protagonist'));
const b = [];
let c = 0;
let a = false;
dataTags.forEach(e => {
if (tagProtNames.length >= 1) {
if (tagProtNames.includes(e)) {
b.push(e);
return;
}
}
if (dislikes.includes(e)) {
c += 1;
}
});
console.debug(c);
if (c > 0) {
return false;
}
if (b.length > 0) {
b.forEach(e => {
tagProt = tagProt.filter(r => r !== e);
});
for (let i = tagProt.length - 1; i >= 0; i--) {
if (dataTags.includes(tagProt[i])) {
return true;
}
a = true;
}
}
console.debug(`b = ${b} tagProt = ${tagProt}`);
return !a;
}
document.querySelector('.content-block_filter').append(mainFilter());
history.onpushstate = function (state) {
setTimeout(init, 200);
};
(function (history) {
var pushState = history.pushState;
history.pushState = function (state) {
if (typeof history.onpushstate == "function") {
history.onpushstate({
state: state
});
}
return pushState.apply(history, arguments);
};
})(window.history);
}());