Amazon Enhancements: Ratings Display and Filtering

Display rating scores and add filtering capabilities on Amazon search results.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey, Greasemonkey или Violentmonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Violentmonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Violentmonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Userscripts.

Чтобы установить этот скрипт, сначала вы должны установить расширение браузера, например Tampermonkey.

Чтобы установить этот скрипт, вы должны установить расширение — менеджер скриптов.

(у меня уже есть менеджер скриптов, дайте мне установить скрипт!)

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

(у меня уже есть менеджер стилей, дайте мне установить скрипт!)

// ==UserScript==
// @name Amazon Enhancements: Ratings Display and Filtering
// @namespace http://tampermonkey.net/
// @version 2.3
// @description Display rating scores and add filtering capabilities on Amazon search results.
// @author Dave w/ Claudi.ai & ChatGPT
// @match https://*.amazon.com/s?*
// @grant none
// @license MIT
// ==/UserScript==

(function() {
    'use strict';

    let currentFilter = 0;

    // Function to enhance rating display
    const enhanceRatingDisplay = (result) => {
        const ratingElement = result.querySelector('i.a-icon-star-small span.a-icon-alt');
        if (ratingElement && !result.classList.contains('enhanced-rating')) {
            const ratingText = ratingElement.textContent.trim();
            const ratingValue = parseFloat(ratingText.split(' ')[0]);
            const newRatingElement = document.createElement('span');
            newRatingElement.textContent = ratingValue + ' ';
            newRatingElement.style.fontWeight = 'bold';
            newRatingElement.style.color = '#007600'; // Change color if needed
            newRatingElement.style.marginRight = '5px'; // Add some spacing between the ratings
            ratingElement.parentElement.parentElement.insertBefore(newRatingElement, ratingElement.parentElement);
            result.dataset.ratingValue = ratingValue;
            result.classList.add('enhanced-rating');
        }
    };

    // Function to add filter dropdown and refresh icon
    const addFilterDropdown = () => {
        const filterBar = document.createElement('div');
        filterBar.id = 'rating-filter-bar';

        const filterLabel = document.createElement('span');
        filterLabel.textContent = 'Filter by star rating: ';
        filterLabel.style.marginRight = '5px';
        filterBar.appendChild(filterLabel);

        const filterDropdown = document.createElement('select');
        filterDropdown.style.marginRight = '10px';

        // Define dropdown options and their actions
        const filters = [
            { text: 'All', score: 0 },
            { text: '4.9+', score: 4.9 },
            { text: '4.8+', score: 4.8 },
            { text: '4.7+', score: 4.7 },
            { text: '4.6+', score: 4.6 },
            { text: '4.5+', score: 4.5 },
            { text: '4.4+', score: 4.4 },
            { text: '4.3+', score: 4.3 },
            { text: '4.2+', score: 4.2 },
            { text: '4.1+', score: 4.1 }
        ];

        filters.forEach(filter => {
            const option = document.createElement('option');
            option.value = filter.score;
            option.textContent = filter.text;
            filterDropdown.appendChild(option);
        });

        filterDropdown.addEventListener('change', (event) => {
            currentFilter = parseFloat(event.target.value);
            filterResults(currentFilter);
        });

        filterBar.appendChild(filterDropdown);

        const refreshIcon = document.createElement('span');
        refreshIcon.innerHTML = '↻'; // HTML entity for refresh icon
        refreshIcon.style.cursor = 'pointer';
        refreshIcon.style.marginLeft = '5px';
        refreshIcon.addEventListener('click', () => {
            filterResults(currentFilter);
        });

        filterBar.appendChild(refreshIcon);

        // Insert the filter bar at the top of the search results
        const searchResults = document.querySelector('div.s-main-slot.s-result-list.s-search-results.sg-row');
        if (searchResults) {
            searchResults.insertBefore(filterBar, searchResults.firstChild);
        }
    };

    // Function to filter results based on rating score
    const filterResults = (minScore) => {
        const results = document.querySelectorAll('div[data-asin]:not(.s-pagination-container)');
        results.forEach(result => {
            if (!result.querySelector('.s-pagination-container')) {
                const ratingValue = parseFloat(result.dataset.ratingValue);
                result.style.display = ratingValue >= minScore ? '' : 'none';
            }
        });
    };

    // Function to process search results
    const processSearchResults = () => {
        const searchResults = document.querySelectorAll('div[data-asin]:not(.s-pagination-container)');
        searchResults.forEach(result => {
            enhanceRatingDisplay(result);
        });
        filterResults(currentFilter);
    };

    // Throttle function to limit the rate of execution
    const throttle = (func, delay) => {
        let timeoutId = null;
        return (...args) => {
            if (timeoutId === null) {
                func(...args);
                timeoutId = setTimeout(() => {
                    timeoutId = null;
                }, delay);
            }
        };
    };

    // Throttled version of processSearchResults
    const throttledProcessSearchResults = throttle(processSearchResults, 500);

    // Observe changes in the search results
    const observeSearchResults = () => {
        const searchResultsContainer = document.querySelector('div.s-main-slot.s-result-list.s-search-results.sg-row');
        if (searchResultsContainer) {
            const observer = new MutationObserver(throttledProcessSearchResults);
            observer.observe(searchResultsContainer, {
                childList: true,
                subtree: true
            });
        }
    };

    // Initialize the script
    const init = () => {
        addFilterDropdown();
        processSearchResults();
        observeSearchResults();
    };

    // Run the script when the page has loaded
    window.addEventListener('load', init);
})();