Greasy Fork

Kinopoisk - Add to folder

Добавить фильм в папку

目前为 2025-01-06 提交的版本。查看 最新版本

// ==UserScript==
// @name         Kinopoisk - Add to folder
// @namespace    scriptomatika
// @author       mouse-karaganda
// @description  Добавить фильм в папку
// @license      MIT
// @match        https://*.kinopoisk.ru/film/*
// @match        https://*.kinopoisk.ru/series/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=kinopoisk.ru
// @version      1.4
// @grant        none
// ==/UserScript==

(function() {
    let $ = window.jQuery;
    console.log('kinoscript :: userscript run at == ', location.href);

    let poisk = {};

    let plugin = {
        insertStyle: function() {
            if ($('style[name="kinoscript"]').length > 0) {
                return;
            }
            let styleText = [
                '.styles_userFoldersContainer { margin-bottom: 24px; }',
                '.styles_userFoldersContainer .btn_outer { display: flex; justify-content: center; cursor: pointer; font-weight: bold; color: #3bb33b; }',
                '.styles_userFoldersContainer .btn_outer:hover { color: #266fff; }',
                '.styles_userFoldersContainer .btn_outer .button { margin: 0 8px; }',
                '.styles_userFoldersContainer .btn_outer .arrow_right { transform: rotate(90deg); }',
                'div[class*=styles_rootDark] .styles_userFoldersContainer .menu_outer { background-color: #000000; color: white; }',
                '.styles_userFoldersContainer .menu_outer { position: absolute; left: 0; right: 0; z-index: 10; padding: 12px 0; border: 2px dotted #3bb33b; border-radius: 12px; background-color: #ffffff; }',
                '.styles_userFoldersContainer .menu_inner { height: 250px; overflow-x: hidden; overflow-y: scroll; scrollbar-width: thin; }',
                '.styles_userFoldersContainer .menu_outer .item { display: flex; justify-content: space-between; padding: 8px 20px; margin: 4px 0; cursor: pointer; }',
                '.styles_userFoldersContainer .menu_outer .item:hover { background-color: rgba(0, 0, 0, 0.04) }',
                '.styles_userFoldersContainer .menu_outer .item:hover .button { color: #266fff; }',

                '.styles_userFoldersContainer.opened .btn_outer .arrow_right,',
                '.styles_userFoldersContainer:not(.opened) .btn_outer .arrow_down,',
                '.styles_userFoldersContainer:not(.opened) .btn_outer .count,',
                '.styles_userFoldersContainer:not(.opened) .menu_outer,',
                '.styles_userFoldersContainer .menu_outer .item:not(.select) .mark { display: none; }'
            ];
            $('<style name="kinoscript" type="text/css" />').appendTo(document.head)
                .text(styleText.join('\n'));
        },

        createFoldersButton: function() {
            let foldersMenu = $('div[class*=styles_foldersMenu]').parents('div[class*=styles_userControlsContainer]');
            console.log('kinoscript :: foldersMenu = ', foldersMenu);
            if (foldersMenu.length == 0) {
                return;
            }
            poisk.section = $('<div />').insertBefore(foldersMenu).addClass('styles_userFoldersContainer styles_section');

            poisk.link = $('<div />').addClass('btn_outer').appendTo(poisk.section).on('click', plugin.openFolderList);
            $('<span />').addClass('arrow_down').text('🔻').appendTo(poisk.link);
            $('<span />').addClass('arrow_right').text('🔺').appendTo(poisk.link);
            $('<span />').addClass('button').text('Список папок').appendTo(poisk.link);
            poisk.count = $('<span />').addClass('count').text('(0)').appendTo(poisk.link);

            let menuOuter = $('<div />').addClass('menu_outer').appendTo(poisk.section);
            poisk.menu = $('<div />').addClass('menu_inner').appendTo(menuOuter);
        },

        openFolderList: function(evt) {
            evt.preventDefault();
            evt.stopPropagation();

            poisk.menu.empty();
            poisk.count.text('(0)');

            // Открытое меню нужно закрыть
            if (poisk.section.hasClass('opened')) {
                poisk.section.removeClass('opened');
                return;
            }

            let random = Math.round(Math.random() * 1e8);
            $.post('/handler_mustsee_ajax.php?mode=multiple&rnd=' + random, {
                //mode: multiple | single
                token: plugin.cookie('_csrf_csrf_token'),
                id_films: plugin.getCurrentFilm()
            }, function(data) {
                console.log('kinoscript :: openFolderList POST = ', data);
                if (data.folders.length == 0) {
                    return;
                }

                poisk.section.addClass('opened');
                let filmId = plugin.getCurrentFilm();
                let selectedCount = 0;

                data.folders.forEach((folder, index) => {
                    let info = {
                        'data-id': folder.id,
                        'data-urladd': `/handler_mykp/folders/${folder.id}/film/${filmId}/`
                    };
                    let div = $('<div />').addClass('item').attr(info).appendTo(poisk.menu)
                        .on('click', plugin.toggleFilmToFolder);
                    $('<span />').addClass('button').html(folder.name).appendTo(div);
                    $('<span />').addClass('mark').text('✔️').appendTo(div);

                    if (filmId in data.objFolders) {
                        if (folder.id in data.objFolders[filmId]) {
                            div.addClass('select');
                            selectedCount++;
                        }
                    }
                });

                poisk.count.text(`(${selectedCount})`);
            });
        },

        toggleFilmToFolder: function(evt) {
            console.log('kinoscript :: toggleFilmToFolder = ', evt, this);
            let urlAdd = $(this).data('urladd');
            console.log('kinoscript :: toggleFilmToFolder urlAdd = ', plugin.cookie('_csrf_csrf_token'));

            $.post(urlAdd, {
                token: plugin.cookie('_csrf_csrf_token')
            }, function(data) {
                console.log('kinoscript :: toggleFilmToFolder post = ', data);
            });
        },

        cookie: function(name) {
            let match = document.cookie.match(new RegExp('\b' + name + '=(.+)(;|$)'));
            console.log('kinoscript :: cookie = ', match);
        },

        getCurrentFilm: function() {
            let match = location.href.match(/\/(film|series)\/(\d+)/);
            if (match) {
                return match[2];
            }
            return '0';
        },

        missingElement: function(elemGetter, callback) {
            // Итерации 10 раз в секунду
            let missingOne = 100;
            // Ограничим количество попыток разумными пределами
            let maxIterCount = 3000;

            let elemTimer;
            let iterCount = 0;

            let missingHandler = () => {
                let elemList = elemGetter();
                // Определим, что вышел элемент
                let elemStop = (elemList.length > 0);
                // Определим, что кончилось количество попыток
                let iterStop = (iterCount >= maxIterCount);

                if (elemStop || iterStop) {
                    clearInterval(elemTimer);

                    // Если элемент так и не появился
                    if (!elemStop && iterStop) {
                        console.log('kinoscript :: Нет элемента = ', elemGetter.toString());
                        return;
                    }
                    if (elemList.length == 1) {
                        elemList = elemList.eq(0);
                    }
                    callback.call(window, elemList);
                }
                iterCount++;
            };
            elemTimer = setInterval(missingHandler, missingOne);
        },

        checkLocation: function () {
            let result = /(film|series)\/\d+\/?$/.test(location.pathname);
            return result;
        },

        checkLibrary: function () {
            if (window.jQuery) {
                plugin.afterLoad();
            } else {
                let tagJS = document.createElement('script');
                tagJS.src = ('https://yastatic.net/jquery/3.3.1/jquery.min.js');
                tagJS.onload = plugin.afterLoad;
                document.body.append(tagJS);
            }
        },

        createChangeTimer: function() {
            $(window).on('kinochange', (evt) => {
                console.log('kinoscript :: kinochange [%o] = %o, jQuery = %o', location.href, evt, window.jQuery);
            });

            let urlChanger = () => {
                if (!plugin.location) {
                    plugin.location = location.href;
                }
                // Если адрес страницы изменился
                if (plugin.location != location.href) {
                    $(window).trigger({
                        type: 'kinochange',
                        oldValue: plugin.location,
                        newValue: location.href
                    });
                    plugin.location = location.href;
                }
            };
            setInterval(urlChanger, 200);
            urlChanger();
        },

        afterLoad: function () {
            //window.jQuery.noConflict();
            $ = window.jQuery;
            console.log('kinoscript :: jQuery = ', $);

            plugin.insertStyle();
            plugin.createChangeTimer();
            plugin.createFoldersButton();
        },

        start: function() {
            console.log('kinoscript :: plugin START [%o] = ', plugin.checkLocation(), location.href);
            //if (!plugin.checkLocation())
            plugin.checkLibrary();

            window.addEventListener('popstate', (evt) => {
                // Эксперимент показал, что popstate на сайте не вызывается,
                // хотя внешний вид страницы изменяется. Вместо него будет
                // кастомное событие kinochange
                console.log('kinoscript :: popstate [%o] = ', location.href, evt);
            });
        }
    };

    plugin.start();

    console.log('Kinopoisk - Add to folder 💬 1.4');
})();