Last active
November 13, 2025 07:56
-
-
Save chenasraf/1a983b99448f3a2c09662d6535bf1fa5 to your computer and use it in GitHub Desktop.
YouTube Members Only Dimmer
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // ==UserScript== | |
| // @name YouTube Members Only Dimmer | |
| // @namespace http://tampermonkey.net/ | |
| // @version 0.3.0 | |
| // @description Make Members Only videos semi-transparent in the feed | |
| // @author Chen Asraf <contact@casraf.dev> | |
| // @match https://www.youtube.com/* | |
| // @icon https://www.google.com/s2/favicons?sz=64&domain=youtube.com | |
| // @grant none | |
| // @updateURL https://gist.github.com/chenasraf/1a983b99448f3a2c09662d6535bf1fa5/raw/youtube-members-only-dimmer.user.js | |
| // @downloadURL https://gist.github.com/chenasraf/1a983b99448f3a2c09662d6535bf1fa5/raw/youtube-members-only-dimmer.user.js | |
| // ==/UserScript== | |
| (function() { | |
| 'use strict'; | |
| let observer = null; | |
| function processVideoItems() { | |
| // Find all video grid items | |
| const videoItems = document.querySelectorAll('ytd-rich-item-renderer'); | |
| videoItems.forEach(item => { | |
| // Skip if already processed | |
| if (item.dataset.membersOnlyProcessed) return; | |
| // Check if this item has a "Members only" badge | |
| let delta = 0 | |
| let int = setInterval(() => { | |
| const membersBadge = item.querySelector('.badge-style-type-members-only'); | |
| delta += 10 | |
| if (membersBadge) { | |
| // Apply opacity to the entire video item | |
| item.style.opacity = '0.1'; | |
| item.dataset.membersOnly = 'true'; | |
| clearInterval(int); | |
| return; | |
| } | |
| if (delta >= 1000) { | |
| item.dataset.membersOnly = 'false'; | |
| clearInterval(int); | |
| } | |
| }, 10); | |
| item.dataset.membersOnlyProcessed = 'true'; | |
| }); | |
| } | |
| function startObserver() { | |
| const feedContainer = document.querySelector('#primary #contents'); | |
| if (!feedContainer) { | |
| // If feed container not found yet, try again after a short delay | |
| setTimeout(startObserver, 500); | |
| return; | |
| } | |
| // Process existing items | |
| processVideoItems(); | |
| // Create observer to watch for new items being added | |
| observer = new MutationObserver((mutations) => { | |
| processVideoItems(); | |
| }); | |
| // Start observing | |
| observer.observe(feedContainer, { | |
| childList: true, | |
| subtree: true | |
| }); | |
| console.log('YouTube Members Only Dimmer: Observer started'); | |
| } | |
| function stopObserver() { | |
| if (observer) { | |
| observer.disconnect(); | |
| observer = null; | |
| console.log('YouTube Members Only Dimmer: Observer stopped'); | |
| } | |
| } | |
| // Start when page loads | |
| if (document.readyState === 'loading') { | |
| document.addEventListener('DOMContentLoaded', startObserver); | |
| } else { | |
| startObserver(); | |
| } | |
| // Handle YouTube SPA navigation | |
| let lastUrl = location.href; | |
| new MutationObserver(() => { | |
| const currentUrl = location.href; | |
| if (currentUrl !== lastUrl) { | |
| lastUrl = currentUrl; | |
| stopObserver(); | |
| setTimeout(startObserver, 500); | |
| } | |
| }).observe(document.querySelector('body'), { | |
| childList: true, | |
| subtree: true | |
| }); | |
| })(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment