您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds a useful "tool box" to the top of the side bar on the subscriptions page (Filter Subs by name, sort them by amount, toggle on/off visibility of subs with 0 new wallpapers)
- // ==UserScript==
- // @name [Wallhaven] Subscription Tools
- // @namespace NooScripts
- // @author NooScripts
- // @version 1.6
- // @description Adds a useful "tool box" to the top of the side bar on the subscriptions page (Filter Subs by name, sort them by amount, toggle on/off visibility of subs with 0 new wallpapers)
- // @license MIT
- // @match https://wallhaven.cc/subscription*
- // @grant none
- // ==/UserScript==
- window.addEventListener('load', () => {
- 'use strict';
- // Create container for search tools
- const container = document.createElement('div');
- container.id = 'custom-tag-filter';
- container.style.display = 'flex';
- container.style.flexDirection = 'column';
- container.style.alignItems = 'center';
- container.style.gap = '8px';
- container.style.padding = '10px';
- container.style.background = '#111';
- container.style.zIndex = '9999';
- // Search input
- const input = document.createElement('input');
- input.type = 'text';
- input.placeholder = 'Filter tags...';
- input.style.padding = '6px';
- input.style.width = '100%';
- input.style.background = '#222';
- input.style.color = '#fff';
- input.style.border = '1px solid #555';
- input.style.borderRadius = '4px';
- // Create a container for buttons
- const buttonsContainer = document.createElement('div');
- buttonsContainer.style.display = 'flex';
- buttonsContainer.style.gap = '8px';
- buttonsContainer.style.width = '100%';
- buttonsContainer.style.margin = 'auto';
- // Reset button
- const resetBtn = document.createElement('button');
- resetBtn.textContent = 'Reset';
- resetBtn.style.padding = '6px 10px';
- resetBtn.style.background = '#333';
- resetBtn.style.color = '#fff';
- resetBtn.style.border = '1px solid #555';
- resetBtn.style.borderRadius = '4px';
- resetBtn.style.cursor = 'pointer';
- resetBtn.style.flex = '1';
- // Toggle style button
- const toggleBtn = document.createElement('button');
- toggleBtn.style.padding = '6px 10px';
- toggleBtn.style.background = '#333';
- toggleBtn.style.color = '#fff';
- toggleBtn.style.border = '1px solid #555';
- toggleBtn.style.borderRadius = '4px';
- toggleBtn.style.cursor = 'pointer';
- toggleBtn.style.flex = '1';
- // Append buttons to the buttons container
- buttonsContainer.appendChild(resetBtn);
- buttonsContainer.appendChild(toggleBtn);
- // Append input and buttons container to the main container
- container.appendChild(input);
- container.appendChild(buttonsContainer);
- // Insert above .sidebar-background
- const sidebarBg = document.querySelector('.sidebar-background');
- if (sidebarBg && sidebarBg.parentNode) {
- sidebarBg.parentNode.insertBefore(container, sidebarBg);
- } else {
- console.warn('⚠️ Could not find sidebar');
- }
- // Initialize styleEnabled from localStorage or default to true
- let styleEnabled = localStorage.getItem('styleEnabled') !== null
- ? JSON.parse(localStorage.getItem('styleEnabled'))
- : true;
- const styleSheet = document.createElement('style');
- document.head.appendChild(styleSheet);
- // Set initial button text and stylesheet based on styleEnabled
- toggleBtn.textContent = styleEnabled ? 'Show Empty' : 'Hide Empty';
- styleSheet.textContent = styleEnabled ? `
- .blocklist.subscription-list li:is([class=""]) {
- display: none !important;
- }
- ` : '';
- // Load saved input text from localStorage
- input.value = localStorage.getItem('filterText') || '';
- if (input.value) performFiltering(); // Apply filter if there's saved text
- // Add or remove the CSS to hide empty <li> elements
- function toggleStyle() {
- styleEnabled = !styleEnabled;
- localStorage.setItem('styleEnabled', JSON.stringify(styleEnabled)); // Save to localStorage
- if (styleEnabled) {
- styleSheet.textContent = `
- .blocklist.subscription-list li:is([class=""]) {
- display: none !important;
- }
- `;
- toggleBtn.textContent = 'Show Empty';
- } else {
- styleSheet.textContent = '';
- toggleBtn.textContent = 'Hide Empty';
- }
- }
- // Function to get all li elements in blocklist
- function getTagItems() {
- return Array.from(document.querySelectorAll('ul.blocklist.subscription-list li'));
- }
- // Perform filtering based on input
- function performFiltering() {
- const term = input.value.toLowerCase().trim();
- localStorage.setItem('filterText', input.value); // Save input text to localStorage
- const items = getTagItems();
- items.forEach(li => {
- const tag = li.querySelector('.tagname');
- if (!tag) return;
- const tagText = tag.textContent.toLowerCase();
- li.style.display = tagText.includes(term) ? '' : 'none';
- });
- }
- // Reset the filter
- function resetFilter() {
- const items = getTagItems();
- items.forEach(li => li.style.display = '');
- input.value = '';
- localStorage.setItem('filterText', ''); // Clear saved input text
- }
- // Add event listeners
- input.addEventListener('input', performFiltering);
- resetBtn.addEventListener('click', resetFilter);
- toggleBtn.addEventListener('click', toggleStyle);
- });
- //Script 2: Sort Subscriptions By Number
- function sortListItems(descending) {
- const container = document.querySelector('[data-storage-id="tagsubscriptions"]');
- if (!container) {
- console.error('Tag subscriptions container not found.');
- return;
- }
- const listItems = Array.from(container.querySelectorAll('.blocklist[class*="subscription-list"] [class*="has-"]'));
- listItems.sort((a, b) => {
- const valueA = parseInt(a.querySelector('small').textContent);
- const valueB = parseInt(b.querySelector('small').textContent);
- return descending ? valueB - valueA : valueA - valueB;
- });
- listItems.forEach((item) => {
- const parent = item.parentNode;
- parent.appendChild(item);
- });
- }
- function createDropdown(labelText, options, onChange) {
- const dropdown = document.createElement('select');
- options.forEach(option => {
- const optionElement = document.createElement('option');
- optionElement.value = option.value;
- optionElement.text = option.text;
- dropdown.appendChild(optionElement);
- });
- dropdown.addEventListener('change', onChange);
- const label = document.createElement('label');
- label.style.marginRight = '10px';
- label.appendChild(document.createTextNode(labelText + ': '));
- label.appendChild(dropdown);
- return label;
- }
- function handleSortDropdownChange() {
- if (this.value === 'default') {
- localStorage.removeItem('subscriptionSortOrder');
- location.reload();
- return;
- }
- const descending = this.value === 'desc';
- sortListItems(descending);
- localStorage.setItem('subscriptionSortOrder', descending ? 'desc' : 'asc');
- }
- function handleDisplayDropdownChange() {
- const existingStyle = document.getElementById('display-filter-style');
- if (existingStyle) {
- existingStyle.remove();
- }
- let css = '';
- switch (this.value) {
- case 'sfw':
- css = `
- [class="has-new "]:has([class="tagname sketchy"]) {display: none!important;}
- [class="has-new "]:has([class="tagname nsfw"]) {display: none!important;}
- `;
- break;
- case 'sketch':
- css = `
- [class="has-new "]:has([class="tagname sfw"]) {display: none!important;}
- [class="has-new "]:has([class="tagname nsfw"]) {display: none!important;}
- `;
- break;
- case 'nsfw':
- css = `
- [class="has-new "]:has([class="tagname sfw"]) {display: none!important;}
- [class="has-new "]:has([class="tagname sketchy"]) {display: none!important;}
- `;
- break;
- }
- if (css) {
- const style = document.createElement('style');
- style.id = 'display-filter-style';
- style.textContent = css;
- document.head.appendChild(style);
- }
- localStorage.setItem('subscriptionDisplayFilter', this.value);
- }
- function initializeDropdown() {
- const sortDropdownOptions = [
- { value: 'default', text: 'Default' },
- { value: 'desc', text: 'Most to Least' },
- { value: 'asc', text: 'Least To Most' }
- ];
- const displayDropdownOptions = [
- { value: 'all', text: 'All' },
- { value: 'sfw', text: 'Only SFW' },
- { value: 'sketch', text: 'Only Sketch' },
- { value: 'nsfw', text: 'Only NSFW' }
- ];
- const sortDropdown = createDropdown('Sort Order', sortDropdownOptions, handleSortDropdownChange);
- const displayDropdown = createDropdown('Display', displayDropdownOptions, handleDisplayDropdownChange);
- const container = document.createElement('div');
- container.id = 'sort-dropdown-container';
- container.style.padding = '0px 0px 8px 0px';
- container.style.marginBottom = '10px';
- container.style.backgroundColor = '#111111';
- container.style.borderBottom = '1px solid #4a4a4a';
- container.style.fontSize = '12px';
- container.style.display = 'flex';
- container.style.alignItems = 'center';
- container.style.gap = '10px';
- container.appendChild(sortDropdown);
- container.appendChild(displayDropdown);
- const sidebarBackground = document.querySelector('.sidebar-background');
- if (sidebarBackground) {
- sidebarBackground.insertBefore(container, sidebarBackground.firstChild);
- } else {
- console.error('.sidebar-background element not found.');
- }
- const sortOrder = localStorage.getItem('subscriptionSortOrder');
- if (sortOrder === 'desc') {
- sortDropdown.querySelector('select').value = 'desc';
- sortListItems(true);
- } else if (sortOrder === 'asc') {
- sortDropdown.querySelector('select').value = 'asc';
- sortListItems(false);
- }
- const displayFilter = localStorage.getItem('subscriptionDisplayFilter');
- if (displayFilter) {
- displayDropdown.querySelector('select').value = displayFilter;
- handleDisplayDropdownChange.call(displayDropdown.querySelector('select'));
- }
- }
- initializeDropdown();