Filelist.io Size Filter

Add sliders and dropdown menus to filter filelist.io results by size

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name         Filelist.io Size Filter
// @version      0.2
// @description  Add sliders and dropdown menus to filter filelist.io results by size
// @author       konvar
// @match        https://filelist.io/browse.php*
// @grant        none
// @namespace https://greasyfork.org/users/1228860
// ==/UserScript==

(function () {
    'use strict';

    // Your existing HTML block
    const existingForm = document.querySelector('table tbody tr td form');

    // Create a div to hold sliders and dropdown menus
    const filterContainer = document.createElement('div');
    filterContainer.style.display = 'flex';
    filterContainer.style.justifyContent = 'center';
    filterContainer.style.alignItems = 'center';
    filterContainer.style.flexWrap = 'wrap'; // Allow flex items to wrap
    filterContainer.style.marginTop = '10px'; // Adjust the top margin
    filterContainer.style.marginBottom = '10px'; // Adjust the bottom margin

    // Create dropdown menus for minimum and maximum size
    const minSizeDropdown = createDropdown('Min Size:', 'minSizeDropdown', ['KB', 'MB', 'GB', 'TB']);
    const maxSizeDropdown = createDropdown('Max Size:', 'maxSizeDropdown', ['KB', 'MB', 'GB', 'TB']);

    // Set default values for dropdowns if not present in localStorage
    minSizeDropdown.value = localStorage.getItem('minSizeDropdown') || 'KB';
    maxSizeDropdown.value = localStorage.getItem('maxSizeDropdown') || 'TB';

    // Create sliders for minimum and maximum size
    const minSizeSlider = createSlider('Min Size:', 'minSizeSlider', 0, 999);
    const maxSizeSlider = createSlider('Max Size:', 'maxSizeSlider', 0, 999);

    // Append the div containing sliders and dropdown menus after the existing form
    existingForm.appendChild(filterContainer);

    // Function to create sliders
    function createSlider(labelText, sliderId, minValue, maxValue) {
        const sliderContainer = document.createElement('div');
        sliderContainer.style.display = 'flex';
        sliderContainer.style.flexDirection = 'row'; // Display label, slider, and value in a row
        sliderContainer.style.alignItems = 'center';
        sliderContainer.style.margin = '0 10px';

        const label = document.createElement('label');
        label.textContent = labelText;
        label.style.marginRight = '5px'; // Adjust margin for spacing
        sliderContainer.appendChild(label);

        const slider = document.createElement('input');
        slider.type = 'range';
        slider.id = sliderId;
        slider.min = minValue;
        slider.max = maxValue;
        slider.value = minValue;

        // Retrieve saved value from localStorage
        const savedValue = localStorage.getItem(sliderId);
        if (savedValue !== null) {
            slider.value = savedValue;
        }

        sliderContainer.appendChild(slider);

        // Display current value
        const valueSpan = document.createElement('span');
        valueSpan.id = sliderId + 'Value';
        valueSpan.textContent = `${parseFloat(slider.value).toFixed(2)} ${sliderId.includes('min') ? minSizeDropdown.value : maxSizeDropdown.value}`;
        valueSpan.style.marginLeft = '5px'; // Adjust margin for spacing
        sliderContainer.appendChild(valueSpan);

        // Add event listener to update the displayed value and save to localStorage
        slider.addEventListener('input', function () {
            const unit = sliderId.includes('min') ? minSizeDropdown.value : maxSizeDropdown.value;
            valueSpan.textContent = `${parseFloat(slider.value).toFixed(2)} ${unit}`;
            localStorage.setItem(sliderId, slider.value);

            // Call the function to filter results based on size
            filterTorrentResults(
                parseFloat(minSizeSlider.value),
                parseFloat(maxSizeSlider.value),
                minSizeDropdown.value,
                maxSizeDropdown.value
            );
        });

        // Append slider to the common div
        filterContainer.appendChild(sliderContainer);

        return slider;
    }

    // Function to create dropdown menus
    function createDropdown(labelText, dropdownId, options) {
        const dropdownContainer = document.createElement('div');
        dropdownContainer.style.display = 'flex';
        dropdownContainer.style.flexDirection = 'row'; // Display label, dropdown in a row
        dropdownContainer.style.alignItems = 'center';
        dropdownContainer.style.margin = '0 10px';

        const label = document.createElement('label');
        label.textContent = labelText;
        label.style.marginRight = '5px'; // Adjust margin for spacing
        dropdownContainer.appendChild(label);

        const dropdown = document.createElement('select');
        dropdown.id = dropdownId;

        // Create options for the dropdown
        options.forEach((option) => {
            const optionElement = document.createElement('option');
            optionElement.value = option;
            optionElement.text = option;
            dropdown.appendChild(optionElement);
        });

        // Retrieve saved value from localStorage
        const savedValue = localStorage.getItem(dropdownId);
        if (savedValue !== null) {
            dropdown.value = savedValue;
        }

        dropdownContainer.appendChild(dropdown);

        // Add event listener to update the displayed value and save to localStorage
        dropdown.addEventListener('change', function () {
            localStorage.setItem(dropdownId, dropdown.value);
            // Call the function to filter results based on size
            filterTorrentResults(
                parseFloat(minSizeSlider.value),
                parseFloat(maxSizeSlider.value),
                minSizeDropdown.value,
                maxSizeDropdown.value
            );
        });

        // Append dropdown to the common div
        filterContainer.appendChild(dropdownContainer);

        return dropdown;
    }

    // Add event listeners to dropdown menus
    minSizeDropdown.addEventListener('change', updateUnitAndFilter);
    maxSizeDropdown.addEventListener('change', updateUnitAndFilter);

    // Function to update the displayed filter values and unit
    function updateUnitAndFilter() {
        const minSizeUnit = minSizeDropdown.value;
        const maxSizeUnit = maxSizeDropdown.value;

        // Ensure that the minimum unit is smaller than or equal to the maximum unit
        if (minSizeDropdown.selectedIndex > maxSizeDropdown.selectedIndex) {
            // Swap the values if the order is incorrect
            const temp = minSizeDropdown.value;
            minSizeDropdown.value = maxSizeDropdown.value;
            maxSizeDropdown.value = temp;
        }

        // Update the displayed unit for the sliders
        document.getElementById('minSizeSliderValue').textContent = `${parseFloat(minSizeSlider.value).toFixed(2)} ${minSizeDropdown.value}`;
        document.getElementById('maxSizeSliderValue').textContent = `${parseFloat(maxSizeSlider.value).toFixed(2)} ${maxSizeDropdown.value}`;

        // Save the selected units to localStorage
        localStorage.setItem('minSizeDropdown', minSizeDropdown.value);
        localStorage.setItem('maxSizeDropdown', maxSizeDropdown.value);

        // Call the function to filter results based on size
        filterTorrentResults(
            parseFloat(minSizeSlider.value),
            parseFloat(maxSizeSlider.value),
            minSizeUnit,
            maxSizeUnit
        );
    }

   // Add event listener to update the displayed value and save to localStorage for minSizeSlider
    minSizeSlider.addEventListener('input', function () {
    const unit = minSizeDropdown.value;
    const maxValue = parseFloat(maxSizeSlider.value);

    // Update the displayed value
    const valueSpan = document.getElementById('minSizeSliderValue');
    valueSpan.textContent = `${parseFloat(minSizeSlider.value).toFixed(2)} ${unit}`;

    // Save to localStorage
    localStorage.setItem('minSizeSlider', minSizeSlider.value);

    // Check if the new minimum value is greater than the current maximum value
    if (parseFloat(minSizeSlider.value) > maxValue && minSizeDropdown.value === maxSizeDropdown.value) {
        // If yes, update the maximum slider to the new minimum value
        maxSizeSlider.value = minSizeSlider.value;
        // Update the displayed value for the maximum slider
        document.getElementById('maxSizeSliderValue').textContent = `${parseFloat(maxSizeSlider.value).toFixed(2)} ${unit}`;
        // Save to localStorage
        localStorage.setItem('maxSizeSlider', maxSizeSlider.value);
    }

    // Call the function to filter results based on size
    filterTorrentResults(
        parseFloat(minSizeSlider.value),
        parseFloat(maxSizeSlider.value),
        minSizeDropdown.value,
        maxSizeDropdown.value
    );
});


    // Function to update the displayed filter values
    function updateFilter() {
        const minSize = parseFloat(minSizeSlider.value);
        const maxSize = parseFloat(maxSizeSlider.value);

        // Update the displayed unit for the sliders
        document.getElementById('minSizeSliderValue').textContent = `${minSize.toFixed(2)} ${minSizeDropdown.value}`;
        document.getElementById('maxSizeSliderValue').textContent = `${maxSize.toFixed(2)} ${maxSizeDropdown.value}`;

        // Call the function to filter results based on size
        filterTorrentResults(minSize, maxSize, minSizeDropdown.value, maxSizeDropdown.value);
    }

    // Initial setup to set the correct unit for the sliders
    minSizeDropdown.value = localStorage.getItem('minSizeDropdown') || 'KB';
    maxSizeDropdown.value = localStorage.getItem('maxSizeDropdown') || 'KB';
    updateUnitAndFilter(); // Call the function to set the correct unit initially

    // Function to filter torrent results based on size
    function filterTorrentResults(minSize, maxSize, minSizeUnit, maxSizeUnit) {
        const torrentRows = document.querySelectorAll('.torrentrow');
        torrentRows.forEach((row) => {
            const sizeElement = row.querySelector('.torrenttable:nth-child(7) font.small');
            if (sizeElement) {
                const sizeText = sizeElement.textContent.trim(); // Extract size value
                const size = parseSize(sizeText, minSizeUnit);
                const sizeInMaxUnit = convertSize(size, minSizeUnit, maxSizeUnit);

                // Check if the size is greater than or equal to the min size slider
                // and less than or equal to the max size slider
                row.style.display = size >= minSize && sizeInMaxUnit <= maxSize ? '' : 'none';
            }
        });
    }

    // Function to parse sizes and convert them to the selected unit
    function parseSize(sizeText, sizeUnit) {
        const match = sizeText.match(/([\d.]+)\s*([KMGTP]B)/i);
        if (match) {
            const value = parseFloat(match[1]);
            const unit = match[2].toUpperCase();

            return convertSize(value, unit, sizeUnit);
        }
        return 0; // Default to 0 for unrecognized units
    }

    // Function to convert sizes to the selected unit
    function convertSize(value, fromUnit, toUnit) {
        const units = { KB: 1, MB: 1024, GB: 1024 * 1024, TB: 1024 * 1024 * 1024 };

        if (fromUnit in units && toUnit in units) {
            return (value * units[fromUnit]) / units[toUnit];
        }

        return value; // Default to the original value if units are not recognized
    }

    // Watch for changes in the content using MutationObserver
    const observer = new MutationObserver(() => {
        // Reapply filtering when the content changes
        filterTorrentResults(
            parseFloat(minSizeSlider.value),
            parseFloat(maxSizeSlider.value),
            minSizeDropdown.value,
            maxSizeDropdown.value
        );
    });

    // Configure and start the observer
    const config = { childList: true, subtree: true };
    observer.observe(document.body, config);
})();