Избранные каналы Youtube

Выделяет видео избранных каналов среди остальных (только в режиме Сетки). Нажмите значок сердца на странице канала, чтобы добавить его в избранное.

// ==UserScript==
// @name         Youtube favorites channels
// @name:ru      Избранные каналы Youtube
// @namespace    http://tampermonkey.net/
// @version      0.2
// @description  Highlights videos of the channels that you mark as favorite (only for Grid view). Tap the heart icon on the channel page to add it to your favorites.
// @description:ru  Выделяет видео избранных каналов среди остальных (только в режиме Сетки). Нажмите значок сердца на странице канала, чтобы добавить его в избранное.
// @author       dark1103
// @include      https://www.youtube.com/*
// @icon         https://www.google.com/s2/favicons?domain=youtube.com
// @require      http://code.jquery.com/jquery-3.4.1.min.js
// @grant        GM_getValue
// @grant        GM_setValue
// ==/UserScript==

(function() {
    'use strict';
    var bg_color = 'lightgoldenrodyellow';



    function getFav(){
         var fav = GM_getValue("fav1");
        if(fav === undefined){
            fav = [];
        }
        return fav;
    }

    function onLoaded(){
        var name = $('#channel-name #text').eq(0).text();
        var isFav = getFav().includes(name);
        $('#fav-button').remove();
        var node = $('<div id="fav-button" class="style-scope ytd-c4-tabbed-header-renderer" style="line-height: 38px;font-size: large;cursor: pointer;">' + (isFav ? '💖' : '🤍') + '</div>');
        node.appendTo($('#inner-header-container #buttons'));

        node.on('click', function(){

            var fav = getFav();

            if(isFav){
                fav = fav.filter(item => item !== name);
                isFav = false;
            }else{
                fav.push(name);
                isFav = true;
            }

            $('#fav-button').html(isFav ? '💖' : '🤍');
            GM_setValue("fav1", fav);
        });

    }
    function highlightFav(){
        if(location.href === 'https://www.youtube.com/feed/subscriptions'){
            var fav = getFav();
            $('ytd-grid-video-renderer').filter(function(){
                var name = $(this).find('#channel-name #text').text();
                return fav.includes(name);
            }).css('background-color', bg_color);
        }
    }

    function createMutationListener(){
        var target = document.querySelector('body')

        // Create an observer instance linked to the callback function
        const observer2 = new MutationObserver(function(mutationsList, observer) {
            // Use traditional 'for loops' for IE 11
            for(const mutation of mutationsList) {
                if (mutation.type === 'childList') {
                    var target = $(mutation.target);
                    //console.log(target);
                    if(target.prop("tagName") === 'ytd-thumbnail-overlay-time-status-renderer'.toUpperCase()){
                        highlightFav();
                    }
                }
            }
        });

        // Start observing the target node for configured mutations
        observer2.observe(target, { attributes: true, childList: true, subtree: true });
    }

    $(document).ready(function(){
        onLoaded();
        highlightFav();
        createMutationListener();
    });


    var oldHref = document.location.href;
    var bodyList = document.querySelector("body")
        ,observer = new MutationObserver(function(mutations) {

            mutations.forEach(function(mutation) {

                if (oldHref != document.location.href) {
                    oldHref = document.location.href;
                    setTimeout(function(){
                        onLoaded();
                        highlightFav();
                    }, 1000);
                    onLoaded();
                    highlightFav();
                }

            });

        });

    observer.observe(bodyList, {
        childList: true,
        subtree: true
    });

})();