media panel

media panel in the catlife online

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         media panel
// @namespace    http://tampermonkey.net/
// @version      2025-01-19
// @description  media panel in the catlife online
// @author       me
// @match        https://worldcats.ru/play/
// @match        https://worldcats.ru/play/?v=b
// @match        https://catlifeonline.com/play/
// @match        https://catlifeonline.com/play/?v=b
// @icon         https://www.google.com/s2/favicons?sz=64&domain=catlifeonline.com
// @grant        none
// ==/UserScript==

(function() {
    // Проверяем, существует ли уже панель, чтобы избежать дублирования
    if (document.getElementById('media-viewer-panel')) {
        console.log('Панель просмотра медиа уже существует.');
        return;
    }

    // --- 1. Создание структуры панели ---
    const panel = document.createElement('div');
    panel.id = 'media-viewer-panel';

    const header = document.createElement('div');
    header.id = 'media-viewer-header';
    header.innerHTML = 'Медиа-просмотрщик <span id="toggle-btn" style="cursor: pointer;">[ - ]</span>';

    const contentArea = document.createElement('div');
    contentArea.id = 'media-viewer-content';
    contentArea.innerHTML = '<p style="text-align: center; color: #aaa;">Перетащите сюда видео, GIF или фото</p>';

    panel.appendChild(header);
    panel.appendChild(contentArea);
    document.body.appendChild(panel);

    // --- 2. Стилизация и позиционирование (инлайн-стили для простоты в консоли) ---
    panel.style.cssText = `
        position: fixed;
        bottom: 10px;
        left: 10px;
        width: 300px; /* Начальная ширина */
        height: 300px; /* Начальная высота для видимости содержимого */
        max-height: 80vh; /* Максимальная высота относительно окна просмотра */
        min-height: 30px; /* Минимальная высота в свернутом виде (только заголовок) */
        background-color: #222;
        border: 1px solid #444;
        border-radius: 8px;
        box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
        z-index: 10000;
        display: flex;
        flex-direction: column;
        overflow: hidden; /* Скрыть контент при свертывании */
        color: #eee;
        font-family: Arial, sans-serif;
        font-size: 14px;
        resize: both; /* Позволяет изменять размер панели */
        min-width: 150px;
        max-width: 80vw; /* Максимальная ширина относительно окна просмотра */
        transition: width 0.2s ease, height 0.2s ease; /* Плавное изменение размера */
    `;

    header.style.cssText = `
        background-color: #333;
        padding: 8px 12px;
        display: flex;
        justify-content: space-between;
        align-items: center;
        border-bottom: 1px solid #444;
        user-select: none; /* Запрещает выделение текста в заголовке */
    `;

    contentArea.style.cssText = `
        flex-grow: 1;
        padding: 10px;
        overflow-y: auto; /* Прокрутка для содержимого */
        display: flex;
        flex-direction: column;
        gap: 10px; /* Промежуток между элементами */
        justify-content: flex-start; /* Элементы начинаются сверху */
        align-items: center; /* Центрирование медиа по горизонтали */
        min-width: 100px; /* Минимальная ширина контентной области */
        min-height: 50px; /* Минимальная высота контентной области */
    `;

    // --- 3. Функциональность свертывания/развертывания панели ---
    const toggleBtn = document.getElementById('toggle-btn');
    let isCollapsed = false;toggleBtn.onclick = function() {
        if (isCollapsed) {
            contentArea.style.display = 'flex';
            panel.style.height = '300px'; // Возвращаем к начальной высоте
            panel.style.maxHeight = '80vh'; // Возвращаем максимальную высоту
            toggleBtn.textContent = '[ - ]';
        } else {
            contentArea.style.display = 'none';
            panel.style.height = '30px'; // Сворачиваем до высоты заголовка
            panel.style.maxHeight = '30px'; // Ограничиваем максимальную высоту
            toggleBtn.textContent = '[ + ]';
        }
        isCollapsed = !isCollapsed;
    };

    // --- 4. Функциональность Drag and Drop ---
    contentArea.addEventListener('dragover', (e) => {
        e.preventDefault(); // Разрешаем drop
        contentArea.style.backgroundColor = 'rgba(68, 68, 68, 0.3)'; // Визуальная обратная связь
    });

    contentArea.addEventListener('dragleave', (e) => {
        contentArea.style.backgroundColor = 'transparent'; // Убираем обратную связь
    });

    contentArea.addEventListener('drop', (e) => {
        e.preventDefault();
        contentArea.style.backgroundColor = 'transparent'; // Убираем обратную связь

        const files = e.dataTransfer.files;
        if (files.length > 0) {
            // Удаляем начальное сообщение "Перетащите сюда..."
            if (contentArea.querySelector('p')) {
                contentArea.innerHTML = '';
            }

            for (let i = 0; i < files.length; i++) {
                const file = files[i];
                // Проверяем тип файла: изображение или видео
                if (file.type.startsWith('image/') || file.type.startsWith('video/')) {
                    // Создаем обертку для медиа и кнопки удаления
                    const mediaWrapper = document.createElement('div');
                    mediaWrapper.style.cssText = `
                        position: relative;
                        border: 1px solid #555;
                        border-radius: 4px;
                        overflow: hidden;
                        margin-bottom: 5px; /* Отступ между элементами */
                        box-shadow: 0 2px 5px rgba(0,0,0,0.2);
                        width: 100%; /* Обертка занимает всю доступную ширину */
                        display: flex; /* Для центрирования медиа внутри обертки */
                        justify-content: center;
                        align-items: center;
                        min-height: 50px; /* Минимальная высота для маленьких файлов */
                    `;

                    let mediaElement;
                    let objectURL; // Переменная для хранения URL, чтобы потом его отозвать

                    if (file.type.startsWith('image/')) {
                        mediaElement = document.createElement('img');
                        mediaElement.alt = file.name;
                        objectURL = URL.createObjectURL(file);
                        mediaElement.src = objectURL;
                    } else if (file.type.startsWith('video/')) {
                        mediaElement = document.createElement('video');
                        mediaElement.controls = true; // Добавляем элементы управления видео
                        mediaElement.autoplay = false; // Не автовоспроизводить по умолчанию
                        mediaElement.loop = true; // Зацикливать видео
                        mediaElement.muted = true; // Отключаем звук по умолчанию

                        objectURL = URL.createObjectURL(file);
                        mediaElement.src = objectURL;// *** Обработка ошибок для видео ***
                        mediaElement.onerror = function(e) {
                            console.error(`Ошибка загрузки или воспроизведения медиа: ${file.name}.`, e);
                            const errorDiv = document.createElement('div');
                            errorDiv.style.cssText = `
                                color: red;
                                padding: 10px;
                                text-align: center;
                                background-color: #333;
                                border-top: 1px solid #555;
                                width: 100%;
                            `;
                            errorDiv.textContent = `Ошибка: Не удалось загрузить или воспроизвести "${file.name}"`;

                            mediaWrapper.innerHTML = ''; // Очищаем обертку
                            mediaWrapper.appendChild(errorDiv);
                            mediaWrapper.appendChild(closeButton); // Важно: заново добавить кнопку закрытия

                            // Отозвать URL, если ошибка произошла после его создания
                            if (objectURL) {
                                URL.revokeObjectURL(objectURL);
                                objectURL = null; // Обнуляем, чтобы не пытаться отозвать дважды
                            }
                        };
                    }

                    mediaElement.style.maxWidth = '100%'; // Масштабирование по ширине панели
                    mediaElement.style.height = 'auto'; // Сохранение пропорций
                    mediaElement.style.display = 'block';
                    mediaElement.style.borderRadius = '3px'; // Небольшое скругление углов медиа

                    // Добавляем кнопку удаления
                    const closeButton = document.createElement('span');
                    closeButton.classList.add('close-button'); // Добавляем класс для идентификации
                    closeButton.innerHTML = '&times;'; // Символ "крестик"
                    closeButton.style.cssText = `
                        position: absolute;
                        top: 5px;
                        right: 5px;
                        background-color: rgba(0, 0, 0, 0.6);
                        color: white;
                        border-radius: 50%;
                        width: 20px;
                        height: 20px;
                        display: flex;
                        align-items: center;
                        justify-content: center;
                        cursor: pointer;
                        font-size: 16px;
                        font-weight: bold;
                        line-height: 1; /* Для лучшего выравнивания символа */
                        padding-bottom: 2px;
                        transition: background-color 0.2s ease;
                        z-index: 1; /* Убедимся, что кнопка поверх медиа */
                    `;
                    closeButton.title = 'Удалить файл';
                    // Эффект при наведении
                    closeButton.onmouseover = () => closeButton.style.backgroundColor = 'rgba(255, 0, 0, 0.7)';
                    closeButton.onmouseout = () => closeButton.style.backgroundColor = 'rgba(0, 0, 0, 0.6)';

                    closeButton.onclick = () => {
                        mediaWrapper.remove(); // Удаляем всю обертку с медиа
                        // Очень важно: отзываем URL, чтобы освободить память
                        if (objectURL) {
                            URL.revokeObjectURL(objectURL);
                            console.log(`URL отозван: ${objectURL}`);
                        }
                        // Если больше нет медиа, показываем подсказку снова
                        if (contentArea.children.length === 0) {
                            contentArea.innerHTML = '<p style="text-align: center; color: #aaa;">Перетащите сюда видео, GIF или фото</p>';
                        }
                    };mediaWrapper.appendChild(mediaElement);
                    mediaWrapper.appendChild(closeButton);
                    contentArea.appendChild(mediaWrapper);
                    // Прокручиваем к низу, чтобы показать новый контент
                    contentArea.scrollTop = contentArea.scrollHeight;
                } else {
                    console.warn(`Медиа-просмотрщик: Неподдерживаемый тип файла: ${file.name} (${file.type})`);
                }
            }
        }
    });

    console.log('Медиа-просмотрщик активирован. Панель в левом нижнем углу.');
    console.log('Панель неперемещаема, но ее можно изменять по размеру, потянув за края.');
    console.warn('Внимание: Запуск скриптов из консоли может быть небезопасным. Используйте этот скрипт только на надежных сайтах и понимая, что он делает.');

})();