您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Advanced filter for YouTube Subscriptions with Tabs and filters for Uploads, Live, Upcoming, Shorts, Members Only, and All.
// ==UserScript== // @name YouTube Subscriptions Tab Filter - Advanced (with Members Only) // @namespace http://tampermonkey.net/ // @version 2.6 // @description Advanced filter for YouTube Subscriptions with Tabs and filters for Uploads, Live, Upcoming, Shorts, Members Only, and All. // @author ChatGPT // @license MIT // @include *://*.youtube.com/** // @exclude *://*.youtube.com/watch* // @grant none // ==/UserScript== (function () { 'use strict'; const ALL_TABS = ['Uploads', 'Live', 'Upcoming', 'Shorts', 'Members Only', 'All']; let enabledTabs = JSON.parse(localStorage.getItem('yt_sub_filter_tabs_enabled') || JSON.stringify(ALL_TABS)); let lastTab = 'Uploads'; // Default to "Uploads" tab let debounceTimeout; let isFiltering = false; const waitForGrid = setInterval(() => { const grid = document.querySelector('ytd-rich-grid-renderer'); if (grid && document.querySelectorAll('ytd-rich-item-renderer').length > 0) { clearInterval(waitForGrid); createConfigBar(); createTabBar(); filterVideos(lastTab); observeGridChanges(); } }, 500); function createTabBar() { const container = document.querySelector('ytd-rich-grid-renderer'); if (!container) return; const tabBar = document.createElement('div'); tabBar.id = 'yt-tab-filter-bar'; tabBar.style.display = 'flex'; tabBar.style.gap = '10px'; tabBar.style.margin = '10px 10px 0 10px'; tabBar.style.flexWrap = 'wrap'; enabledTabs.forEach(tabName => { const btn = document.createElement('button'); btn.textContent = tabName; btn.style.padding = '5px 10px'; btn.style.cursor = 'pointer'; btn.style.border = '1px solid #aaa'; btn.style.background = '#eee'; btn.style.borderRadius = '4px'; btn.style.fontWeight = tabName === lastTab ? 'bold' : 'normal'; btn.onclick = () => { document.querySelectorAll('#yt-tab-filter-bar button').forEach(b => b.style.fontWeight = 'normal'); btn.style.fontWeight = 'bold'; lastTab = tabName; filterVideos(tabName); }; tabBar.appendChild(btn); }); container.parentElement.insertBefore(tabBar, container); } function createConfigBar() { const container = document.querySelector('ytd-rich-grid-renderer'); if (!container) return; const configBar = document.createElement('div'); configBar.style.margin = '10px'; configBar.style.display = 'flex'; configBar.style.flexWrap = 'wrap'; configBar.style.gap = '8px'; const label = document.createElement('span'); label.textContent = 'Enable Tabs: '; configBar.appendChild(label); ALL_TABS.forEach(tab => { const toggle = document.createElement('input'); toggle.type = 'checkbox'; toggle.checked = enabledTabs.includes(tab); toggle.id = `toggle-${tab}`; toggle.onchange = () => { if (toggle.checked) { if (!enabledTabs.includes(tab)) enabledTabs.push(tab); } else { enabledTabs = enabledTabs.filter(t => t !== tab); if (lastTab === tab) lastTab = 'Uploads'; } localStorage.setItem('yt_sub_filter_tabs_enabled', JSON.stringify(enabledTabs)); document.querySelector('#yt-tab-filter-bar')?.remove(); createTabBar(); filterVideos(lastTab); }; const lbl = document.createElement('label'); lbl.textContent = tab; lbl.style.marginRight = '10px'; lbl.style.userSelect = 'none'; lbl.htmlFor = toggle.id; configBar.appendChild(toggle); configBar.appendChild(lbl); }); container.parentElement.insertBefore(configBar, container); } function filterVideos(filter) { if (isFiltering) return; isFiltering = true; const items = document.querySelectorAll('ytd-rich-item-renderer'); items.forEach(item => { const text = item.textContent.toLowerCase(); const hasNotify = item.querySelector('span.yt-core-attributed-string--white-space-no-wrap')?.textContent.includes('Notify me'); const isLive = /\blive\b/.test(text); // Only match 'live' as a whole word const isUpcoming = !!hasNotify; const isShort = text.includes('#shorts') || isLikelyShort(item); const isMembers = text.includes('members only'); let show = false; if (!enabledTabs.includes(filter)) { show = true; // If the tab is disabled, show all items } else { switch (filter) { case 'All': show = true; break; case 'Uploads': show = !isLive && !isUpcoming && !isShort && !isMembers; break; case 'Live': show = isLive; break; case 'Upcoming': show = isUpcoming && !isLive && !isShort && !isMembers; break; case 'Shorts': show = isShort; break; case 'Members Only': show = isMembers; break; } } item.style.display = show ? '' : 'none'; }); isFiltering = false; } function isLikelyShort(item) { const durationLabel = item.querySelector('span.ytd-thumbnail-overlay-time-status-renderer'); if (durationLabel) { const duration = durationLabel.textContent.trim(); const parts = duration.split(':').map(Number); let seconds = 0; if (parts.length === 2) seconds = parts[0] * 60 + parts[1]; else if (parts.length === 3) seconds = parts[0] * 3600 + parts[1] * 60 + parts[2]; return seconds > 0 && seconds < 60; } return false; } function observeGridChanges() { const grid = document.querySelector('ytd-rich-grid-renderer #contents'); if (!grid) return; const observer = new MutationObserver(() => { clearTimeout(debounceTimeout); debounceTimeout = setTimeout(() => { filterVideos(lastTab); }, 300); // Delay filtering until scrolling stops }); observer.observe(grid, { childList: true, subtree: true }); } })();