// ==UserScript== // @name Lolz.live Emoji Tooltip & Toggle // @namespace http://tampermonkey.net/ // @version 2.1 // @description Выводит увеличенный смайлик в красивом тултипе при наведении в панели смайликов lolz.live, плюс кнопка вкл/выкл. // @author Replit Agent // @match *://lolz.live/* // @match *://zelenka.guru/* // @grant GM_addStyle // ==/UserScript== (function() { 'use strict'; // 1. Добавляем стили для тултипа, размытия и переключателя GM_addStyle(` /* Контейнер для всплывающего тултипа */ #emoji-enlarger-tooltip { position: fixed; pointer-events: none; z-index: 999999; opacity: 0; transform: translateY(10px) scale(0.9); transition: opacity 0.2s ease, transform 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275); background: rgba(30, 30, 30, 0.7); /* Темный полупрозрачный фон */ backdrop-filter: blur(8px); /* Размытие в стиле 7TV */ -webkit-backdrop-filter: blur(8px); border-radius: 8px; padding: 10px; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.4); display: flex; align-items: center; justify-content: center; /* Начальные размеры, будут подгоняться */ min-width: 60px; min-height: 60px; } #emoji-enlarger-tooltip.show { opacity: 1; transform: translateY(0) scale(1); } #emoji-enlarger-tooltip img { width: auto !important; height: auto !important; max-width: 120px !important; /* Ограничение максимального размера */ max-height: 120px !important; object-fit: contain; } /* Переключатель вкл/выкл в шапке смайлов */ .emoji-enlarger-toggle-header { display: flex; align-items: center; gap: 6px; padding: 8px 10px; background: rgba(0, 0, 0, 0.1); border-bottom: 1px solid rgba(0, 0, 0, 0.15); cursor: pointer; user-select: none; } .emoji-enlarger-toggle-label { font-size: 12px; color: #888; transition: color 0.2s; font-weight: 500; } .emoji-enlarger-toggle-header:hover .emoji-enlarger-toggle-label { color: #bbb; } .emoji-enlarger-switch { position: relative; width: 28px; height: 16px; background: #444; border-radius: 8px; transition: background 0.3s; flex-shrink: 0; } .emoji-enlarger-switch::after { content: ''; position: absolute; top: 2px; left: 2px; width: 12px; height: 12px; background: #fff; border-radius: 50%; transition: transform 0.3s; } .emoji-enlarger-switch.active { background: #22c55e; /* Зеленый цвет при включении */ } .emoji-enlarger-switch.active::after { transform: translateX(12px); } `); // Состояние: включено ли увеличение let isEnabled = localStorage.getItem('lzt_emoji_enlarger') !== 'false'; let isTooltipLocked = false; // 2. Создаем DOM-элемент тултипа const tooltip = document.createElement('div'); tooltip.id = 'emoji-enlarger-tooltip'; const tooltipImg = document.createElement('img'); tooltip.appendChild(tooltipImg); document.body.appendChild(tooltip); // 3. Логика наведения на смайлики document.addEventListener('mouseover', function(e) { if (!isEnabled) return; const target = e.target; // Проверяем, что цель - изображение смайлика (в редакторе или в тексте) if (target.tagName === 'IMG' && (target.classList.contains('smilie') || target.classList.contains('fr-emoticon') || target.classList.contains('mceSmilie'))) { // Берем URL картинки tooltipImg.src = target.src; // Показываем тултип tooltip.classList.add('show'); isTooltipLocked = true; // Позиционируем над курсором/смайликом const rect = target.getBoundingClientRect(); // Помещаем чуть выше смайлика по центру let top = rect.top - tooltip.offsetHeight - 10; let left = rect.left + (rect.width / 2) - (tooltip.offsetWidth / 2); // Если уходит за верхний край экрана, показываем под смайликом if (top < 0) { top = rect.bottom + 10; } tooltip.style.top = top + 'px'; tooltip.style.left = left + 'px'; } // Если наведение на звездочку - не скрываем тултип if (target.classList.contains('like-smilie') || target.closest('.smilie')) { isTooltipLocked = true; } }); document.addEventListener('mouseout', function(e) { if (!isEnabled) return; const target = e.target; // Не скрываем при наведении на звездочку if (target.classList.contains('like-smilie')) { return; } if (target.tagName === 'IMG' && (target.classList.contains('smilie') || target.classList.contains('fr-emoticon') || target.classList.contains('mceSmilie'))) { // Проверяем, не наведен ли курсор на соседнюю звездочку const parentLi = target.closest('li'); if (parentLi) { const star = parentLi.querySelector('.like-smilie'); if (star && e.relatedTarget === star) { isTooltipLocked = true; return; } } isTooltipLocked = false; tooltip.classList.remove('show'); } }); // Скрываем при скролле, чтобы тултип не висел в воздухе document.addEventListener('scroll', function() { tooltip.classList.remove('show'); isTooltipLocked = false; }, {passive: true}); // 4. Интеграция кнопки-переключателя в шапку смайлов function injectToggle() { // Ищем контейнер с смайлами const smilieBox = document.querySelector('.SmilieBox'); const lztFeSmilies = smilieBox ? smilieBox.querySelector('.lzt-fe-smilies') : null; // Если контейнер есть, и мы еще не добавили переключатель if (lztFeSmilies && !document.querySelector('.emoji-enlarger-toggle-header')) { // Создаем контейнер переключателя для шапки const toggleHeader = document.createElement('div'); toggleHeader.className = 'emoji-enlarger-toggle-header'; toggleHeader.title = 'Увеличение смайлов при наведении'; const toggleLabel = document.createElement('span'); toggleLabel.className = 'emoji-enlarger-toggle-label'; toggleLabel.innerText = 'Zoom'; const switchEl = document.createElement('div'); switchEl.className = 'emoji-enlarger-switch'; if (isEnabled) switchEl.classList.add('active'); toggleHeader.appendChild(toggleLabel); toggleHeader.appendChild(switchEl); // Вставляем в самое начало lzt-fe-smilies lztFeSmilies.insertBefore(toggleHeader, lztFeSmilies.firstChild); // Обработчик клика toggleHeader.addEventListener('click', function(e) { e.stopPropagation(); // чтобы не открывалось меню смайлов isEnabled = !isEnabled; isTooltipLocked = false; localStorage.setItem('lzt_emoji_enlarger', isEnabled); if (isEnabled) { switchEl.classList.add('active'); } else { switchEl.classList.remove('active'); tooltip.classList.remove('show'); // Сразу скрываем, если было открыто } }); } } // Запускаем проверку добавления кнопки при загрузке injectToggle(); // Используем MutationObserver для отслеживания появления редактора (на случай если он подгружается аяксом) const observer = new MutationObserver(function(mutations) { if (!document.querySelector('.emoji-enlarger-toggle-header')) { injectToggle(); } }); observer.observe(document.body, { childList: true, subtree: true }); })();