Greasy Fork is available in English.
Hide torrent rows based on checkbox state
// ==UserScript==// @name RED Torrent Filter// @namespace http://tampermonkey.net/// @version 0.5// @description Hide torrent rows based on checkbox state// @author darisk// @match https://redacted.sh/torrents.php?id=*// @icon https://redacted.sh/static/favicon.ico// @grant none// @license GNU GPLv3// ==/UserScript==// Configurationconst FILTER_BOX_POSITION = 2; // Use 2 for second child, 3 for third child// Initialize global variableslet isToggled = false;let previousCheckboxStates = [];let showOnlyCheckbox;(function() {'use strict';addFilterBox();addToggleLink();applyFilter();})();function applyFilter() {if (isToggled) {const torrents = Array.from(document.getElementsByClassName('group_torrent'));torrents.forEach(row => {row.style.display = '';});updateToggleLink(0);return;}const hideSources = {Vinyl: window.localStorage.hideVinyl === "true",Web: window.localStorage.hideWeb === "true",CD: window.localStorage.hideCD === "true",SACD: window.localStorage.hideSACD === "true"};const hideFormats = {MP3: window.localStorage.hideMP3 === "true",FLAC: window.localStorage.hideFLAC === "true",DSD: window.localStorage.hideDSD === "true"};const showOnly24Bit = document.getElementById('showOnly24Bit').checked;const torrents = Array.from(document.getElementsByClassName('group_torrent'));let hiddenCount = 0;let currentEditionGroup = [];for (let i = 0; i < torrents.length; i++) {const row = torrents[i];const isEditionRow = row.classList.contains('edition');if (isEditionRow && currentEditionGroup.length > 0) {hiddenCount += filterEditionGroup(currentEditionGroup, hideSources, hideFormats, showOnly24Bit);currentEditionGroup = [];}currentEditionGroup.push(row);// Filter individual torrent rows if not in an edition groupif (!isEditionRow) {const rowText = row.textContent.toLowerCase();const is24Bit = rowText.includes('24bit lossless') || rowText.includes('dsd') || rowText.includes('dts');let hideRow =(hideFormats.MP3 && (rowText.includes('mp3') || rowText.includes('aac'))) ||(hideFormats.FLAC && rowText.includes('flac')) ||(hideFormats.DSD && (rowText.includes('dsd') || rowText.includes('dxd'))) ||(showOnly24Bit && !is24Bit);if (hideRow) {row.style.display = 'none';hiddenCount++;} else {row.style.display = '';}}}// Handle the last edition group if anyif (currentEditionGroup.length > 0) {hiddenCount += filterEditionGroup(currentEditionGroup, hideSources, hideFormats, showOnly24Bit);}updateToggleLink(hiddenCount);}function filterEditionGroup(editionGroup, hideSources, hideFormats, showOnly24Bit) {const editionRow = editionGroup[0];const childRows = editionGroup.slice(1);let shouldHideEdition = false;let hiddenCount = 0;editionRow.style.display = '';const editionText = editionRow.textContent.toLowerCase();if ((hideSources.Vinyl && /\bvinyl\b$/i.test(editionText.trim())) ||(hideSources.Web && /\bweb\b$/i.test(editionText.trim())) ||(hideSources.CD && /\bcd\b$/i.test(editionText.trim())) ||(hideSources.SACD && (/\bsacd\b$/i.test(editionText.trim()) || /\bblu-ray\b$/i.test(editionText.trim()) || /\bdvd\b$/i.test(editionText.trim())))) {shouldHideEdition = true;}if (shouldHideEdition) {editionRow.style.display = 'none';childRows.forEach(row => {row.style.display = 'none';hiddenCount++;});} else {childRows.forEach(row => {const rowText = row.textContent.toLowerCase();const is24Bit = rowText.includes('24bit lossless') || rowText.includes('dsd') || rowText.includes('dts');if (showOnly24Bit && !is24Bit) {row.style.display = 'none';} else if ((hideFormats.MP3 && (/\bmp3\b/.test(rowText) || /\baac\b/.test(rowText))) ||(hideFormats.FLAC && /\bflac\b/.test(rowText)) ||(hideFormats.DSD && (/\bdsd\b/.test(rowText) || /\bdxd\b/.test(rowText)))) {row.style.display = 'none';} else {row.style.display = '';}});}// If all child rows are hidden, hide the edition row as wellif (childRows.every(row => row.style.display === 'none')) {editionRow.style.display = 'none';}return hiddenCount;}// Helper function to add checkboxesfunction addCheckboxes(parent, items, headerText, padding = '3px') {const header = document.createElement('p');header.innerHTML = `<strong>${headerText}</strong>`;header.style.marginBottom = padding;parent.appendChild(header);items.forEach(item => {const label = document.createElement('label');const checkbox = document.createElement('input');checkbox.type = 'checkbox';checkbox.id = `hide${item}`;checkbox.checked = window.localStorage[`hide${item}`] === "true";checkbox.addEventListener('change', () => {window.localStorage[`hide${item}`] = checkbox.checked;applyFilter();});label.appendChild(checkbox);label.appendChild(document.createTextNode(` ${item}`));label.style.marginRight = '8px';parent.appendChild(label);});parent.appendChild(document.createElement('br'));parent.appendChild(document.createElement('br'));}function addFilterBox() {const box = document.createElement('div');const sidebar = document.getElementsByClassName('sidebar')[0];const targetChild = FILTER_BOX_POSITION === 1? sidebar.firstChild: sidebar.children[FILTER_BOX_POSITION - 1];box.className = 'box';const header = document.createElement('div');header.className = 'head';header.innerHTML = '<strong>Torrent Filter</strong>';box.appendChild(header);const body = document.createElement('div');body.className = 'body';box.appendChild(body);// Sources and formats checkboxesconst sources = ['Vinyl', 'Web', 'CD', 'SACD'];const formats = ['MP3', 'FLAC', 'DSD'];addCheckboxes(body, sources, 'Hide Sources');addCheckboxes(body, formats, 'Hide Formats');// Show Only 24 Bit checkboxconst showOnlyHeader = document.createElement('p');showOnlyHeader.innerHTML = '<strong>Show Only</strong>';showOnlyHeader.style.marginBottom = '3px';body.appendChild(showOnlyHeader);const showOnlyLabel = document.createElement('label');showOnlyCheckbox = document.createElement('input');showOnlyCheckbox.type = 'checkbox';showOnlyCheckbox.id = 'showOnly24Bit';showOnlyCheckbox.checked = window.localStorage.showOnly24Bit === "true";showOnlyCheckbox.addEventListener('change', () => {window.localStorage.showOnly24Bit = showOnlyCheckbox.checked;applyFilter();});showOnlyLabel.appendChild(showOnlyCheckbox);showOnlyLabel.appendChild(document.createTextNode(' 24 bit'));body.appendChild(showOnlyLabel);sidebar.insertBefore(box, targetChild);}// Function to add a toggle link that also shows hidden row countfunction addToggleLink() {const linkbox = document.querySelector('.linkbox');let toggleLink = linkbox.querySelector('.toggle-link');if (!toggleLink) {toggleLink = document.createElement('a');toggleLink.className = 'toggle-link';toggleLink.href = '#';toggleLink.innerText = '[Toggle Hidden: 0]';toggleLink.addEventListener('click', (e) => {e.preventDefault();const allCheckboxes = document.querySelectorAll('.box input[type="checkbox"]');if (isToggled) {// Restore previous checkbox statesallCheckboxes.forEach((checkbox, index) => {checkbox.checked = previousCheckboxStates[index];window.localStorage[checkbox.id] = checkbox.checked;});showOnlyCheckbox.checked = previousCheckboxStates[allCheckboxes.length];window.localStorage.showOnly24Bit = showOnlyCheckbox.checked;isToggled = false;} else {// Save current checkbox states and uncheck allpreviousCheckboxStates = [...allCheckboxes].map(checkbox => checkbox.checked);previousCheckboxStates.push(showOnlyCheckbox.checked);allCheckboxes.forEach(checkbox => {checkbox.checked = false;window.localStorage[checkbox.id] = checkbox.checked;});showOnlyCheckbox.checked = false;window.localStorage.showOnly24Bit = false;isToggled = true;}applyFilter();});linkbox.appendChild(toggleLink);}}// Function to update the hidden count in the toggle link textfunction updateToggleLink(hiddenCount) {const toggleLink = document.querySelector('.linkbox .toggle-link');if (toggleLink) {toggleLink.innerHTML = `[Toggle Hidden${hiddenCount > 0 ? `: <span style="color: #ff0000;">${hiddenCount}</span>` : ': 0'}]`;}}