Twitch Sort by Newest/Oldest

Sorts Twitch clips by newest or oldest on the 24-hour clips page

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey, Greasemonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Userscripts.

За да инсталирате скрипта, трябва да инсталирате разширение като Tampermonkey.

За да инсталирате този скрипт, трябва да имате инсталиран скриптов мениджър.

(Вече имам скриптов мениджър, искам да го инсталирам!)

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

(Вече имам инсталиран мениджър на стиловете, искам да го инсталирам!)

// ==UserScript==
// @name Twitch Sort by Newest/Oldest
// @namespace http://tampermonkey.net/
// @version 1.0
// @description Sorts Twitch clips by newest or oldest on the 24-hour clips page
// @author MahdeenSky
// @match https://www.twitch.tv/*/clips?filter=clips&range=24hr
// @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
// @grant none
// @license      GNU GPLv3
// ==/UserScript==

(function() {
    'use strict';

    let sortByNewest = true;
    
    function sortClips() {
        console.log(`Sorting clips by ${sortByNewest ? 'newest' : 'oldest'}...`);
    
        const clipTowers = document.querySelectorAll('.ScTower-sc-1sjzzes-0');
        const clipTower = clipTowers[1];
    
        if (clipTower) {
            console.log("Found clip tower element:", clipTower);
        } else {
            console.error("Clip tower element not found!");
            return; // Exit if the main container is not found
        }
    
        const clipCards = Array.from(clipTower.querySelectorAll('.Layout-sc-1xcs6mc-0[data-a-target^="clips-card-"]'));
        console.log("Found", clipCards.length, "clip cards.");
    
        clipCards.sort((a, b) => {
            const elementA = a.querySelectorAll('.ScPositionCorner-sc-1shjvnv-1');
            const elementB = b.querySelectorAll('.ScPositionCorner-sc-1shjvnv-1');
            const timeA = elementA[elementA.length - 1].textContent.trim();
            const timeB = elementB[elementB.length - 1].textContent.trim();
    
            // edge case, if there is 'Yesterday' in the time, it should be considered as the oldest or newest
            if (timeA.includes('Yesterday')) {
                return sortByNewest ? -999 : 999;
            } else if (timeB.includes('Yesterday')) {
                return sortByNewest ? 999 : -999;
            }
    
            // handle hours ago and minutes ago cases
            let timeAValue = parseInt(timeA);
            let timeBValue = parseInt(timeB);
    
            if (timeA.includes('hour')) {
                timeAValue *= 60;
            }
            if (timeB.includes('hour')) {
                timeBValue *= 60;
            }
    
            return sortByNewest ? timeBValue - timeAValue : timeAValue - timeBValue;
        });
    
        clipTower.innerHTML = '';
        clipCards.forEach(card => clipTower.appendChild(card));
    
        console.log("Clips sorted successfully.");
    }
    
    // Create sort button
    const sortButton = document.createElement('button');
    sortButton.textContent = 'Sort by Newest';
    sortButton.style.backgroundColor = '#6441A5';
    sortButton.style.color = 'white';
    sortButton.style.padding = '10px 20px';
    sortButton.style.border = 'none';
    sortButton.style.cursor = 'pointer';
    sortButton.style.borderRadius = '5px';
    sortButton.style.marginTop = '10px';
    
    sortButton.addEventListener('click', () => {
        sortByNewest = !sortByNewest;
        sortButton.textContent = `Sort by ${sortByNewest ? 'Newest' : 'Oldest'}`;
        sortClips();
    });
    
    function addSortButton() {
        const sortContainer = document.querySelector('div[data-test-selector="sort"]');
        if (sortContainer) {
            console.log("Found sort container element:", sortContainer);
            sortContainer.appendChild(sortButton);
            console.log("Sort button added.");
        } else {
            console.log("Sort container element not found. Setting up observer...");
            const observer = new MutationObserver(mutations => {
                const sortContainer = document.querySelector('div[data-test-selector="sort"]');
                if (sortContainer) {
                    console.log("Sort container element found by observer:", sortContainer);
                    sortContainer.appendChild(sortButton);
                    console.log("Sort button added.");
                    observer.disconnect();
                }
            });
            observer.observe(document.body, { childList: true, subtree: true });
        }
    }
    
    addSortButton();
    })();