GitHub Auto Sort

Automatically sorts GitHub stars by most recently active and repositories by public.

// ==UserScript==
// @name         GitHub Auto Sort
// @description  Automatically sorts GitHub stars by most recently active and repositories by public.
// @icon         https://github.githubassets.com/favicons/favicon-dark.svg
// @version      1.1
// @author       afkarxyz
// @namespace    https://github.com/afkarxyz/misc-scripts/
// @supportURL   https://github.com/afkarxyz/misc-scripts/issues
// @license      MIT
// @match        https://github.com/*
// @grant        GM_setValue
// @grant        GM_getValue
// ==/UserScript==

(function() {
    'use strict';

    const CONFIG = {
        STARS_SORTING: 1, // 0: disabled, 1: enabled
        REPOS_PUBLIC_FILTER: 1 // 0: disabled, 1: enabled
    };

    function saveConfig(key, value) {
        try {
            localStorage.setItem(`github-auto-sort-${key}`, value.toString());
        } catch (e) {
            console.error('Error saving config:', e);
        }
    }

    function loadConfig(key, defaultValue) {
        try {
            const value = localStorage.getItem(`github-auto-sort-${key}`);
            return value !== null ? parseInt(value) : defaultValue;
        } catch (e) {
            console.error('Error loading config:', e);
            return defaultValue;
        }
    }

    CONFIG.STARS_SORTING = loadConfig('STARS_SORTING', CONFIG.STARS_SORTING);
    CONFIG.REPOS_PUBLIC_FILTER = loadConfig('REPOS_PUBLIC_FILTER', CONFIG.REPOS_PUBLIC_FILTER);

    function toggleConfig(key) {
        CONFIG[key] = CONFIG[key] === 1 ? 0 : 1;
        saveConfig(key, CONFIG[key]);
        console.log(`GitHub Auto Sort - ${key}: ${CONFIG[key] === 1 ? 'Enabled' : 'Disabled'}`);
    }

    window.githubAutoSortToggle = {
        starsSort: () => toggleConfig('STARS_SORTING'),
        reposPublicFilter: () => toggleConfig('REPOS_PUBLIC_FILTER')
    };

    function updateRepositoryURL() {
        if (!CONFIG.REPOS_PUBLIC_FILTER) return;

        const url = new URL(window.location.href);

        if (url.searchParams.get('tab') === 'repositories') {
            const expectedParams = ['q', 'type', 'language', 'sort'];
            const needsUpdate = expectedParams.some(param =>
                url.searchParams.get(param) === null
            );

            if (needsUpdate) {
                url.searchParams.set('q', '');
                url.searchParams.set('type', 'public');
                url.searchParams.set('language', '');
                url.searchParams.set('sort', '');

                window.history.replaceState({}, '', url.toString());

                const turboFrame = document.querySelector('turbo-frame#user-repositories-list');
                if (turboFrame) {
                    turboFrame.setAttribute('src', url.toString());
                } else {
                    location.reload();
                }
            }
        }
    }

    function updateStarSorting() {
        if (!CONFIG.STARS_SORTING) return;

        const url = new URL(window.location.href);
        if (url.searchParams.get('tab') !== 'stars') return;

        const username = url.pathname.split('/')[1];
        const turboFrame = document.querySelector('turbo-frame#user-starred-repos');

        if (turboFrame) {
            const newUrl = new URL(`/${username}`, window.location.origin);
            newUrl.searchParams.set('tab', 'stars');
            newUrl.searchParams.set('sort', 'updated');
            newUrl.searchParams.set('direction', 'desc');

            turboFrame.setAttribute('src', newUrl.toString());
        }
    }

    function updateSorting() {
        updateRepositoryURL();
        updateStarSorting();
    }

    document.addEventListener('DOMContentLoaded', updateSorting);
    document.addEventListener('turbo:load', updateSorting);
    window.addEventListener('popstate', updateSorting);

    updateSorting();

    console.log('GitHub Auto Sort Configuration:', CONFIG);
})();