Sleazy Fork is available in English.
5/29/2025, 1:01:31 PM
// ==UserScript==
// @name Hide Watched Videos on PMVHaven
// @match https://pmvhaven.com/*
// @version 1.0
// @author -
// @description 5/29/2025, 1:01:31 PM
// @namespace https://greasyfork.org/users/1476445
// ==/UserScript==
let RESULTS_CONTAINER;
let HIDE_WATCHED_ADDED = false
let ENABLED = true
function toggleWatchedThumbnails(enabled = ENABLED){
const thumbnails = document.querySelectorAll("div.v-col-sm-6.v-col-md-4.v-col-lg-4.v-col-12, div.v-col-sm-12 v-col-md-6 v-col-lg-4 v-col-12");
thumbnails.forEach(t => {
const match = t.querySelector("span.v-chip") ? t : null;
if(!match) return;
if (enabled === true) match.style.display = "none";
else if (enabled === false) match.style.display = "flex";
})
}
// Check if __nuxt updates, then hide thumbnail elements that have already been watched.
const nuxtObserver = new MutationObserver(
(mutList, obs) => {
for(const mut of mutList){
RESULTS_CONTAINER = document.querySelector("div.v-row:has(:first-child.v-col-sm-6.v-col-md-4.v-col-lg-4.v-col-12), div.v-row:has(:first-child.v-col-sm-12 v-col-md-6 v-col-lg-4 v-col-12)");
if(!RESULTS_CONTAINER) continue;
toggleWatchedThumbnails()
// Add toggle to sidebar
const infiniteScrollSidebarToggle = document.querySelector("#__nuxt > div.v-application.v-theme--dark.v-layout.v-layout--full-height.v-locale--is-ltr > div > div > div > div.v-col-md-3.v-col-lg-3.v-col-3.hidden-md-and-down.pa-0 > div > div:nth-child(1) > div.v-card.v-theme--dark.v-card--density-default.v-card--variant-flat.mb-2.mt-3 > div:nth-child(3)")
const infiniteScrollFilterToggle = document.querySelector("body > div.v-overlay-container > div > div.v-overlay__content > div > div:nth-child(7) > div")
if(!infiniteScrollSidebarToggle) continue;
if(!HIDE_WATCHED_ADDED){
const hideWatchedToggle = infiniteScrollSidebarToggle.cloneNode(true)
const input = hideWatchedToggle.querySelector("input[aria-label='Infinite Scrolling']")
const label = hideWatchedToggle.querySelector("label")
label.innerText = "Hide Watched"
label.setAttribute('for', "hideWatched")
input.setAttribute('id', "hideWatched")
input.value = ENABLED
function toggle(toggled){
const control = hideWatchedToggle.querySelector("div.v-selection-control")
const thumb = hideWatchedToggle.querySelector("div.v-switch__thumb")
const track = hideWatchedToggle.querySelector("div.v-switch__track")
if(toggled){
control.classList.toggle("v-selection-control--dirty", true)
control.classList.toggle("v-selection-control--focused", false)
thumb.classList.toggle("bg-orange", true)
track.classList.toggle("bg-orange", true)
} else {
control.classList.toggle("v-selection-control--dirty", false)
control.classList.toggle("v-selection-control--focused", true)
thumb.classList.toggle("bg-orange", false)
track.classList.toggle("bg-orange", false)
}
}
hideWatchedToggle.querySelector(".v-selection-control").addEventListener("mouseup", e => {
ENABLED = !ENABLED
input.value = ENABLED
toggleWatchedThumbnails(ENABLED)
toggle(ENABLED)
})
infiniteScrollSidebarToggle.after(hideWatchedToggle)
// infiniteScrollFilterToggle.after(hideWatchedToggle)
HIDE_WATCHED_ADDED = true
}
}
}
)
nuxtObserver.observe(document.querySelector("div#__nuxt"), { childList: true, subtree: true })