Greasy Fork

Greasy Fork is available in English.

Improved Channel Select Menu for Kbin

Adds subscribed magazines and liked collections to the channel select menu.

当前为 2024-01-08 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         Improved Channel Select Menu for Kbin
// @namespace    http://tampermonkey.net/
// @version      0.1.0
// @description  Adds subscribed magazines and liked collections to the channel select menu.
// @author       NeighborlyFedora
// @match        *://kbin.social/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=kbin.social
// @require      https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js
// @license      GPL-3.0-or-later
// ==/UserScript==

//Code partially based on Floating Subs List by raltsm4k (http://greasyfork.icu/en/scripts/469121-floating-subs-list)

let user;
let subs = [];
let clls = [];
let subs_html = [];
let clls_html = [];
let fetch_tries = 3;

(function() {
    'use strict';

    user = document.querySelector('#header a.login').getAttribute('href');

    if(user === '/login') return;

    const channel_list = document.querySelector('#header li:has(a[title="Select a channel"]) .dropdown__menu');
    Object.assign(channel_list, {
        id: 'channel-list'
    });

    const refresher = Object.assign(document.createElement('button'), {
        id: 'refresher',
        title: 'Refresh list',
    });
    refresher.appendChild(Object.assign(document.createElement('i'), {
        className: 'fa-solid fa-rotate'
    }));
    channel_list.prepend(refresher);
    refresher.addEventListener('click', function(){
        localStorage.removeItem('icsm_' + user);
        empty();
        $('#refresher').find('i').addClass('fa-spin');
        fetch_subs(1);
    });

    $('<style>').text(
        `
        #header #channel-list {
            scroll-behavior: auto;
            width: 25rem;
            height: 25rem;
            overflow-x: hidden;
            overflow-y: scroll;
        }

        #header #channel-list h3 {
            border-bottom: var(--kbin-sidebar-header-border);
            color: var(--kbin-sidebar-header-text-color);
            font-size: .8rem;
            width: 95%;
            margin: 1rem 0 0 2.5%;
            text-transform: uppercase;
        }

        #header #channel-list #refresher {
            display: inline !important;
            position: absolute;
            background: none;
            border: 0;
            color: var(--kbin-meta-link-color);
            cursor: pointer;
            height: auto;
            width: auto;
            text-indent: 0;
            right: 2.5%;
            text-align: right;
            margin: 1rem 0 0 1rem;
            padding: 0 !important;
        }

        #header #channel-list #refresher:hover {
            color: var(--kbin-meta-link-hover-color);
        }

        #header #channel-list li {
            height: auto;
        }

        #header #channel-list #sub_item a:has(figure) {
            display: flex !important;
            justify-content: left;
        }

        #header #channel-list a {
            overflow-x: hidden;
            position: relative;
            padding: .35rem 1rem !important;
        }

        #header #channel-list #sub_item figure{
            float: left;
            margin-right: 0.25rem;
        }

        #header #channel-list #sub_item figure img{
            width: 1.25rem;
            height: 1.25rem;
            vertical-align: middle;
        }

        #header #channel-list::-webkit-scrollbar {
            width: 8px;
        }

        .rounded-edges #header #channel-list::-webkit-scrollbar-track {
            border-top-right-radius: var(--kbin-rounded-edges-radius);
            border-bottom-right-radius: var(--kbin-rounded-edges-radius);
        }

        .rounded-edges #header #channel-list::-webkit-scrollbar-thumb  {
            border-radius: var(--kbin-rounded-edges-radius);
        }


        #header #channel-list::-webkit-scrollbar-track {
            background: var(--kbin-bg);
            border-left: var(--kbin-section-border);
        }


        #header #channel-list::-webkit-scrollbar-thumb {
            background: var(--kbin-meta-link-color);
            border-left: var(--kbin-section-border);
            transition-duration: 0.4s;
        }
        #header #channel-list::-webkit-scrollbar-thumb:hover {
            background: var(--kbin-meta-link-hover-color);
        }
        `
    ).appendTo(document.head);
    empty();
    const cache = JSON.parse(localStorage.getItem('icsm_' + user));
    if (cache === null || Date.now() >= cache.expire) {
        $('#refresher').find('i').addClass('fa-spin');
        fetch_subs(1);
    }else{
        console.log('Fetching from cache....');
        cache.subs.forEach(function(cached_html){
           subs.push($(Object.assign(document.createElement('li'),{
               id: 'sub_item'
           })).html(cached_html))
        });

        cache.clls.forEach(function(cached_html){
           clls.push($(Object.assign(document.createElement('li'),{
               id: 'sub_item'
           })).html(cached_html))
        });
        complete();
    }

})();

function empty(){
    subs.forEach((sub) => { sub.remove();} );
    clls.forEach((cll) => { cll.remove();} );
    subs = [];
    subs_html = [];
    clls = [];
    clls_html = [];
}

function fetch_subs(page){
    $.get( window.location.origin + '/settings/subscriptions/magazines?p=' + page, function(data) {
        const $dom = $($.parseHTML(data));
        const $subs_list = $dom.find('#content .magazines ul');
        console.log('Fetching page ' + page + ' of subscriptions....');
        if (!$subs_list.length) {
            if (fetch_tries > 0) {
                console.log('Failed to fetch page ' + page + ' of subscriptions. Retrying....');
                fetch_tries--;
                fetch_subs(page);
            } else {
                console.log('Failed to fetch page ' + page + ' of subscriptions. Out of attempts.');
            }
        }else{
            fetch_tries = 3;
            const $new_subs = $subs_list.children('li');
            $new_subs.each(function() {
                $(this).prop('id', 'sub_item');

                const $link = $(this).find('a');

                const $icon = $(this).find('figure');

                $link.removeClass();
                if(window.location.href.includes('/m/'+$link.text())){
                   $link.addClass('active');
                }

                $link.prepend($icon);
                $(this).append($link);
                $(this).find('small').remove();
                $(this).find('div').remove();
                subs.push($(this));
                subs_html.push($(this).html());
            });
            const $pg = $dom.find('#content .pagination__item--next-page.pagination__item--disabled');

            if ($pg.length) {
                fetch_colls(1);
            } else {
                fetch_subs(page+1);
            }
        }
    });
}


function fetch_colls(page){
    $.get( window.location.origin + '/magazines/collections?p=' + page, function(data) {
        const $dom = $($.parseHTML(data));
        const $clls_list = $dom.find('#content .categories tbody');
        console.log('Fetching page ' + page + ' of collections....');
        if (!$clls_list.length) {
            if (fetch_tries > 0) {
                console.log('Failed to fetch page ' + page + ' of collections. Retrying...');
                fetch_tries--;
                fetch_colls(page);
            } else {
                console.log('Failed to fetch page ' + page + ' of collections. Out of attempts.');
            }
        }else{
            fetch_tries = 3;
            const $new_clls = $clls_list.children('tr:has(button.active)');
            $new_clls.each(function() {

                const $link = $(this).find('td:first-child a');

                $link.removeClass();
                const $li = $(document.createElement('li'));
                $li.prop('id', 'sub_item');
                $li.append($link);
                clls.push($li);
                clls_html.push($li.html());
            });
            const $pg = $dom.find('#content .pagination__item--next-page.pagination__item--disabled');
            if ($pg.length) {
                localStorage.setItem('icsm_' + user, JSON.stringify({subs: subs_html, clls: clls_html, expire: Date.now() + 15 * 60 * 1000}));
                complete();
            } else {
                fetch_colls(page+1);
            }
        }
    });
}



function complete(){

    console.log('Filling menu....');

    $('#refresher').find('i').removeClass('fa-spin');

    $('#channel-list').children('h3').remove();

    $('#channel-list').prepend($(Object.assign(document.createElement('h3'), {
        id: 'cl-header-feeds',
        textContent: 'Feeds'
    })));

    $('#channel-list').prepend($('#refresher'));

    $('#channel-list').append($(Object.assign(document.createElement('h3'), {
        id: 'cl-header-subs',
        textContent: 'Subscribed Magazines'
    })));

    subs.sort(function(a, b){
        return a.find('a').text().trim().toLowerCase().localeCompare(b.find('a').text().trim().toLowerCase());
    });

    subs.forEach(function(sub) {
        $('#channel-list').append(sub);
        const $link = sub.find('a')
        if( window.location.href.endsWith('/m/'+$link.text().trim()) || window.location.href.includes('/m/'+$link.text().trim()+'/') ){
            $link.addClass('active');
        }else{
            $link.removeClass('active');
        }
    })

    $('#channel-list').append($(Object.assign(document.createElement('h3'), {
        id: 'cl-header-clls',
        textContent: 'Liked Collections'
    })));

    clls.sort(function(a, b){
        return a.text().trim().toLowerCase().localeCompare(b.text().trim().toLowerCase());
    });

    clls.forEach(function(cll) {
        $('#channel-list').append(cll);
        const $link = cll.find('a')
        if( window.location.href.includes('/c/'+$link.text().trim()) || window.location.href.includes('/c/'+$link.text().trim()+'/') ){
            $link.addClass('active');
        }else{
            $link.removeClass('active');
        }
    });

    console.log('Done!');

}